Merge "Camera: Enable override to portrait by default" into tm-qpr-dev
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 5d9f335..a6f47d4 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -109,6 +109,7 @@
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseLongArray;
+import android.util.SparseSetArray;
import android.util.TimeUtils;
import android.view.Display;
import android.widget.Toast;
@@ -452,6 +453,12 @@
private final Map<String, String> mAppStandbyProperties = new ArrayMap<>();
/**
+ * Set of apps that were restored via backup & restore, per user, that need their
+ * standby buckets to be adjusted when installed.
+ */
+ private final SparseSetArray<String> mAppsToRestoreToRare = new SparseSetArray<>();
+
+ /**
* List of app-ids of system packages, populated on boot, when system services are ready.
*/
private final ArrayList<Integer> mSystemPackagesAppIds = new ArrayList<>();
@@ -968,13 +975,17 @@
+ standbyBucketToString(newBucket));
}
} else {
- newBucket = getBucketForLocked(packageName, userId,
- elapsedRealtime);
- if (DEBUG) {
- Slog.d(TAG, "Evaluated AOSP newBucket = "
- + standbyBucketToString(newBucket));
+ // Don't update the standby state for apps that were restored
+ if (!(oldMainReason == REASON_MAIN_DEFAULT
+ && (app.bucketingReason & REASON_SUB_MASK)
+ == REASON_SUB_DEFAULT_APP_RESTORED)) {
+ newBucket = getBucketForLocked(packageName, userId, elapsedRealtime);
+ if (DEBUG) {
+ Slog.d(TAG, "Evaluated AOSP newBucket = "
+ + standbyBucketToString(newBucket));
+ }
+ reason = REASON_MAIN_TIMEOUT;
}
- reason = REASON_MAIN_TIMEOUT;
}
}
@@ -1610,18 +1621,29 @@
final int reason = REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_APP_RESTORED;
final long nowElapsed = mInjector.elapsedRealtime();
for (String packageName : restoredApps) {
- // If the package is not installed, don't allow the bucket to be set.
+ // If the package is not installed, don't allow the bucket to be set. Instead, add it
+ // to a list of all packages whose buckets need to be adjusted when installed.
if (!mInjector.isPackageInstalled(packageName, 0, userId)) {
- Slog.e(TAG, "Tried to restore bucket for uninstalled app: " + packageName);
+ Slog.i(TAG, "Tried to restore bucket for uninstalled app: " + packageName);
+ mAppsToRestoreToRare.add(userId, packageName);
continue;
}
- final int standbyBucket = getAppStandbyBucket(packageName, userId, nowElapsed, false);
- // Only update the standby bucket to RARE if the app is still in the NEVER bucket.
- if (standbyBucket == STANDBY_BUCKET_NEVER) {
- setAppStandbyBucket(packageName, userId, STANDBY_BUCKET_RARE, reason,
- nowElapsed, false);
- }
+ restoreAppToRare(packageName, userId, nowElapsed, reason);
+ }
+ // Clear out the list of restored apps that need to have their standby buckets adjusted
+ // if they still haven't been installed eight hours after restore.
+ // Note: if the device reboots within these first 8 hours, this list will be lost since it's
+ // not persisted - this is the expected behavior for now and may be updated in the future.
+ mHandler.postDelayed(() -> mAppsToRestoreToRare.remove(userId), 8 * ONE_HOUR);
+ }
+
+ /** Adjust the standby bucket of the given package for the user to RARE. */
+ private void restoreAppToRare(String pkgName, int userId, long nowElapsed, int reason) {
+ final int standbyBucket = getAppStandbyBucket(pkgName, userId, nowElapsed, false);
+ // Only update the standby bucket to RARE if the app is still in the NEVER bucket.
+ if (standbyBucket == STANDBY_BUCKET_NEVER) {
+ setAppStandbyBucket(pkgName, userId, STANDBY_BUCKET_RARE, reason, nowElapsed, false);
}
}
@@ -2116,15 +2138,24 @@
}
// component-level enable/disable can affect bucketing, so we always
// reevaluate that for any PACKAGE_CHANGED
- mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE, userId, -1, pkgName)
- .sendToTarget();
+ if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
+ mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE, userId, -1, pkgName)
+ .sendToTarget();
+ }
}
if ((Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
Intent.ACTION_PACKAGE_ADDED.equals(action))) {
if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
maybeUnrestrictBuggyApp(pkgName, userId);
- } else {
+ } else if (!Intent.ACTION_PACKAGE_ADDED.equals(action)) {
clearAppIdleForPackage(pkgName, userId);
+ } else {
+ // Package was just added and it's not being replaced.
+ if (mAppsToRestoreToRare.contains(userId, pkgName)) {
+ restoreAppToRare(pkgName, userId, mInjector.elapsedRealtime(),
+ REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_APP_RESTORED);
+ mAppsToRestoreToRare.remove(userId, pkgName);
+ }
}
}
}
diff --git a/core/java/android/animation/AnimationHandler.java b/core/java/android/animation/AnimationHandler.java
index 19606c1..df8a50a 100644
--- a/core/java/android/animation/AnimationHandler.java
+++ b/core/java/android/animation/AnimationHandler.java
@@ -19,10 +19,10 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.Log;
import android.view.Choreographer;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
@@ -40,7 +40,7 @@
public class AnimationHandler {
private static final String TAG = "AnimationHandler";
- private static final boolean LOCAL_LOGV = true;
+ private static final boolean LOCAL_LOGV = false;
/**
* Internal per-thread collections used to avoid set collisions as animations start and end
@@ -78,7 +78,7 @@
* store visible (foreground) requestors; if the set size reaches zero, there are no
* objects in the foreground and it is time to pause animators.
*/
- private final ArraySet<Object> mAnimatorRequestors = new ArraySet<>();
+ private final ArrayList<WeakReference<Object>> mAnimatorRequestors = new ArrayList<>();
private final Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {
@Override
@@ -141,24 +141,9 @@
* tracking obsolete+enabled requestors.
*/
public static void removeRequestor(Object requestor) {
- getInstance().removeRequestorImpl(requestor);
- }
-
- private void removeRequestorImpl(Object requestor) {
- // Also request disablement, in case that requestor was the sole object keeping
- // animators un-paused
- long startTime = System.nanoTime();
- requestAnimatorsEnabled(false, requestor);
- Log.d(TAG, "removeRequestorImpl called requestAnimatorsEnabled after " +
- (System.nanoTime() - startTime));
- mAnimatorRequestors.remove(requestor);
- Log.d(TAG, "removeRequestorImpl removed requestor after " +
- (System.nanoTime() - startTime));
+ getInstance().requestAnimatorsEnabledImpl(false, requestor);
if (LOCAL_LOGV) {
- Log.v(TAG, "removeRequestorImpl for " + requestor);
- for (int i = 0; i < mAnimatorRequestors.size(); ++i) {
- Log.v(TAG, "animatorRequesters " + i + " = " + mAnimatorRequestors.valueAt(i));
- }
+ Log.v(TAG, "removeRequestor for " + requestor);
}
}
@@ -176,25 +161,44 @@
}
private void requestAnimatorsEnabledImpl(boolean enable, Object requestor) {
- long startTime = System.nanoTime();
boolean wasEmpty = mAnimatorRequestors.isEmpty();
setAnimatorPausingEnabled(isPauseBgAnimationsEnabledInSystemProperties());
- Log.d(TAG, "requestAnimatorsEnabledImpl called setAnimatorPausingEnabled after " +
- (System.nanoTime() - startTime));
- if (enable) {
- mAnimatorRequestors.add(requestor);
- } else {
- mAnimatorRequestors.remove(requestor);
+ synchronized (mAnimatorRequestors) {
+ // Only store WeakRef objects to avoid leaks
+ if (enable) {
+ // First, check whether such a reference is already on the list
+ WeakReference<Object> weakRef = null;
+ for (int i = mAnimatorRequestors.size() - 1; i >= 0; --i) {
+ WeakReference<Object> ref = mAnimatorRequestors.get(i);
+ Object referent = ref.get();
+ if (referent == requestor) {
+ weakRef = ref;
+ } else if (referent == null) {
+ // Remove any reference that has been cleared
+ mAnimatorRequestors.remove(i);
+ }
+ }
+ if (weakRef == null) {
+ weakRef = new WeakReference<>(requestor);
+ mAnimatorRequestors.add(weakRef);
+ }
+ } else {
+ for (int i = mAnimatorRequestors.size() - 1; i >= 0; --i) {
+ WeakReference<Object> ref = mAnimatorRequestors.get(i);
+ Object referent = ref.get();
+ if (referent == requestor || referent == null) {
+ // remove requested item or item that has been cleared
+ mAnimatorRequestors.remove(i);
+ }
+ }
+ // If a reference to the requestor wasn't in the list, nothing to remove
+ }
}
- Log.d(TAG, "requestAnimatorsEnabledImpl added/removed after " +
- (System.nanoTime() - startTime));
if (!sAnimatorPausingEnabled) {
// Resume any animators that have been paused in the meantime, otherwise noop
// Leave logic above so that if pausing gets re-enabled, the state of the requestors
// list is valid
resumeAnimators();
- Log.d(TAG, "requestAnimatorsEnabledImpl resumed, returning after " +
- (System.nanoTime() - startTime));
return;
}
boolean isEmpty = mAnimatorRequestors.isEmpty();
@@ -209,12 +213,13 @@
Animator.getBackgroundPauseDelay());
}
}
- Log.d(TAG, "requestAnimatorsEnabledImpl post was/is check after " +
- (System.nanoTime() - startTime));
if (LOCAL_LOGV) {
- Log.v(TAG, enable ? "enable" : "disable" + " animators for " + requestor);
+ Log.v(TAG, (enable ? "enable" : "disable") + " animators for " + requestor
+ + " with pauseDelay of " + Animator.getBackgroundPauseDelay());
for (int i = 0; i < mAnimatorRequestors.size(); ++i) {
- Log.v(TAG, "animatorRequesters " + i + " = " + mAnimatorRequestors.valueAt(i));
+ Log.v(TAG, "animatorRequestors " + i + " = "
+ + mAnimatorRequestors.get(i) + " with referent "
+ + mAnimatorRequestors.get(i).get());
}
}
}
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 13fc2e6..3c0a724 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -511,10 +511,26 @@
@SystemApi
public static final int MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER = 1;
+ /**
+ * State indicating that media transfer to this receiver device is succeeded.
+ *
+ * @hide
+ */
+ public static final int MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED = 2;
+
+ /**
+ * State indicating that media transfer to this receiver device is failed.
+ *
+ * @hide
+ */
+ public static final int MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_FAILED = 3;
+
/** @hide */
@IntDef(prefix = {"MEDIA_TRANSFER_RECEIVER_STATE_"}, value = {
MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
+ MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_FAILED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface MediaTransferReceiverState {}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 162a997..7eacc3c 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1096,7 +1096,7 @@
}
/**
- * Like {@link #getFastDrawable(int)}, but the returned Drawable has a number
+ * Like {@link #getDrawable(int)}, but the returned Drawable has a number
* of limitations to reduce its overhead as much as possible. It will
* never scale the wallpaper (only centering it if the requested bounds
* do match the bitmap bounds, which should not be typical), doesn't
diff --git a/core/java/android/app/trust/ITrustListener.aidl b/core/java/android/app/trust/ITrustListener.aidl
index 6b9d2c73..e4ac0119 100644
--- a/core/java/android/app/trust/ITrustListener.aidl
+++ b/core/java/android/app/trust/ITrustListener.aidl
@@ -24,8 +24,8 @@
* {@hide}
*/
oneway interface ITrustListener {
- void onTrustChanged(boolean enabled, int userId, int flags,
+ void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId, int flags,
in List<String> trustGrantedMessages);
void onTrustManagedChanged(boolean managed, int userId);
void onTrustError(in CharSequence message);
-}
\ No newline at end of file
+}
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 9e825b72..62f755d 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -22,6 +22,7 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.hardware.biometrics.BiometricSourceType;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -45,6 +46,7 @@
private static final String TAG = "TrustManager";
private static final String DATA_FLAGS = "initiatedByUser";
+ private static final String DATA_NEWLY_UNLOCKED = "newlyUnlocked";
private static final String DATA_MESSAGE = "message";
private static final String DATA_GRANTED_MESSAGES = "grantedMessages";
@@ -171,13 +173,14 @@
try {
ITrustListener.Stub iTrustListener = new ITrustListener.Stub() {
@Override
- public void onTrustChanged(boolean enabled, int userId, int flags,
- List<String> trustGrantedMessages) {
+ public void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId,
+ int flags, List<String> trustGrantedMessages) {
Message m = mHandler.obtainMessage(MSG_TRUST_CHANGED, (enabled ? 1 : 0), userId,
trustListener);
if (flags != 0) {
m.getData().putInt(DATA_FLAGS, flags);
}
+ m.getData().putInt(DATA_NEWLY_UNLOCKED, newlyUnlocked ? 1 : 0);
m.getData().putCharSequenceArrayList(
DATA_GRANTED_MESSAGES, (ArrayList) trustGrantedMessages);
m.sendToTarget();
@@ -265,9 +268,14 @@
public void handleMessage(Message msg) {
switch(msg.what) {
case MSG_TRUST_CHANGED:
- int flags = msg.peekData() != null ? msg.peekData().getInt(DATA_FLAGS) : 0;
- ((TrustListener) msg.obj).onTrustChanged(msg.arg1 != 0, msg.arg2, flags,
- msg.getData().getStringArrayList(DATA_GRANTED_MESSAGES));
+ Bundle data = msg.peekData();
+ int flags = data != null ? data.getInt(DATA_FLAGS) : 0;
+ boolean enabled = msg.arg1 != 0;
+ int newlyUnlockedInt =
+ data != null ? data.getInt(DATA_NEWLY_UNLOCKED) : 0;
+ boolean newlyUnlocked = newlyUnlockedInt != 0;
+ ((TrustListener) msg.obj).onTrustChanged(enabled, newlyUnlocked, msg.arg2,
+ flags, msg.getData().getStringArrayList(DATA_GRANTED_MESSAGES));
break;
case MSG_TRUST_MANAGED_CHANGED:
((TrustListener)msg.obj).onTrustManagedChanged(msg.arg1 != 0, msg.arg2);
@@ -284,6 +292,8 @@
/**
* Reports that the trust state has changed.
* @param enabled If true, the system believes the environment to be trusted.
+ * @param newlyUnlocked If true, the system believes the device is newly unlocked due
+ * to the trust changing.
* @param userId The user, for which the trust changed.
* @param flags Flags specified by the trust agent when granting trust. See
* {@link android.service.trust.TrustAgentService#grantTrust(CharSequence, long, int)
@@ -291,7 +301,7 @@
* @param trustGrantedMessages Messages to display to the user when trust has been granted
* by one or more trust agents.
*/
- void onTrustChanged(boolean enabled, int userId, int flags,
+ void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId, int flags,
List<String> trustGrantedMessages);
/**
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index b3435b1..63f7b8e 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -2405,6 +2405,29 @@
*/
}
+ /**
+ * Perform a check on data paths and scheme specific parts of the intent filter.
+ * Return true if it passed.
+ * @hide
+ */
+ public boolean checkDataPathAndSchemeSpecificParts() {
+ final int numDataPath = mDataPaths == null
+ ? 0 : mDataPaths.size();
+ final int numDataSchemeSpecificParts = mDataSchemeSpecificParts == null
+ ? 0 : mDataSchemeSpecificParts.size();
+ for (int i = 0; i < numDataPath; i++) {
+ if (!mDataPaths.get(i).check()) {
+ return false;
+ }
+ }
+ for (int i = 0; i < numDataSchemeSpecificParts; i++) {
+ if (!mDataSchemeSpecificParts.get(i).check()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
/** @hide */
public IntentFilter(Parcel source) {
mActions = new ArrayList<String>();
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index b0b3e9e..ff80ffd 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -427,9 +427,6 @@
// 1 (brighter). Set to Float.NaN if there's no override.
public float screenAutoBrightnessAdjustmentOverride;
- // If true, enables automatic brightness control.
- public boolean useAutoBrightness;
-
// If true, scales the brightness to a fraction of desired (as defined by
// screenLowPowerBrightnessFactor).
public boolean lowPowerMode;
@@ -459,7 +456,6 @@
policy = POLICY_BRIGHT;
useProximitySensor = false;
screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- useAutoBrightness = false;
screenAutoBrightnessAdjustmentOverride = Float.NaN;
screenLowPowerBrightnessFactor = 0.5f;
blockScreenOn = false;
@@ -483,7 +479,6 @@
policy = other.policy;
useProximitySensor = other.useProximitySensor;
screenBrightnessOverride = other.screenBrightnessOverride;
- useAutoBrightness = other.useAutoBrightness;
screenAutoBrightnessAdjustmentOverride = other.screenAutoBrightnessAdjustmentOverride;
screenLowPowerBrightnessFactor = other.screenLowPowerBrightnessFactor;
blockScreenOn = other.blockScreenOn;
@@ -505,7 +500,6 @@
&& useProximitySensor == other.useProximitySensor
&& floatEquals(screenBrightnessOverride,
other.screenBrightnessOverride)
- && useAutoBrightness == other.useAutoBrightness
&& floatEquals(screenAutoBrightnessAdjustmentOverride,
other.screenAutoBrightnessAdjustmentOverride)
&& screenLowPowerBrightnessFactor
@@ -531,7 +525,6 @@
return "policy=" + policyToString(policy)
+ ", useProximitySensor=" + useProximitySensor
+ ", screenBrightnessOverride=" + screenBrightnessOverride
- + ", useAutoBrightness=" + useAutoBrightness
+ ", screenAutoBrightnessAdjustmentOverride="
+ screenAutoBrightnessAdjustmentOverride
+ ", screenLowPowerBrightnessFactor=" + screenLowPowerBrightnessFactor
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index d8ed124..baf8836 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -30,7 +30,6 @@
import android.compat.annotation.ChangeId;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.hardware.BatteryState;
import android.hardware.SensorManager;
import android.hardware.lights.Light;
@@ -1910,11 +1909,6 @@
*/
@RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
public void setStylusEverUsed(@NonNull Context context, boolean stylusEverUsed) {
- if (context.checkCallingPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("You need WRITE_SECURE_SETTINGS permission "
- + "to set stylus ever used.");
- }
Settings.Global.putInt(context.getContentResolver(),
Settings.Global.STYLUS_EVER_USED, stylusEverUsed ? 1 : 0);
}
diff --git a/core/java/android/os/PatternMatcher.java b/core/java/android/os/PatternMatcher.java
index 631c98a..b5425b4 100644
--- a/core/java/android/os/PatternMatcher.java
+++ b/core/java/android/os/PatternMatcher.java
@@ -16,6 +16,7 @@
package android.os;
+import android.util.Log;
import android.util.proto.ProtoOutputStream;
import java.util.Arrays;
@@ -151,6 +152,23 @@
proto.end(token);
}
+ /**
+ * Perform a check on the matcher for the pattern type of {@link #PATTERN_ADVANCED_GLOB}.
+ * Return true if it passed.
+ * @hide
+ */
+ public boolean check() {
+ try {
+ if (mType == PATTERN_ADVANCED_GLOB) {
+ return Arrays.equals(mParsedPattern, parseAndVerifyAdvancedPattern(mPattern));
+ }
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "Failed to verify advanced pattern: " + e.getMessage());
+ return false;
+ }
+ return true;
+ }
+
public int describeContents() {
return 0;
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index a46868e..68e1acb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -523,6 +523,13 @@
public static final int GO_TO_SLEEP_FLAG_NO_DOZE = 1 << 0;
/**
+ * Go to sleep flag: Sleep softly, go to sleep only if there's no wakelock explicitly keeping
+ * the device awake.
+ * @hide
+ */
+ public static final int GO_TO_SLEEP_FLAG_SOFT_SLEEP = 1 << 1;
+
+ /**
* @hide
*/
@IntDef(prefix = { "BRIGHTNESS_CONSTRAINT_TYPE" }, value = {
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index e899f77..65528e3 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -128,7 +128,7 @@
mNames = in.createStringArray();
int numChains = in.readInt();
- if (numChains > 0) {
+ if (numChains >= 0) {
mChains = new ArrayList<>(numChains);
in.readParcelableList(mChains, WorkChain.class.getClassLoader(), android.os.WorkSource.WorkChain.class);
} else {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d6fa02c6..94a6382 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9514,6 +9514,16 @@
"lock_screen_show_silent_notifications";
/**
+ * Indicates whether "seen" notifications should be suppressed from the lockscreen.
+ * <p>
+ * Type: int (0 for false, 1 for true)
+ *
+ * @hide
+ */
+ public static final String LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS =
+ "lock_screen_show_only_unseen_notifications";
+
+ /**
* Indicates whether snooze options should be shown on notifications
* <p>
* Type: int (0 for false, 1 for true)
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index 1507c87..6e6dac5 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -111,6 +111,12 @@
*/
public static final @RequestFlags int FLAG_IME_SHOWING = 0x80;
+ /**
+ * Indicates whether autofill session should reset the fill dialog state.
+ * @hide
+ */
+ public static final @RequestFlags int FLAG_RESET_FILL_DIALOG_STATE = 0x100;
+
/** @hide */
public static final int INVALID_REQUEST_ID = Integer.MIN_VALUE;
@@ -208,7 +214,8 @@
FLAG_PASSWORD_INPUT_TYPE,
FLAG_VIEW_NOT_FOCUSED,
FLAG_SUPPORTS_FILL_DIALOG,
- FLAG_IME_SHOWING
+ FLAG_IME_SHOWING,
+ FLAG_RESET_FILL_DIALOG_STATE
})
@Retention(RetentionPolicy.SOURCE)
@DataClass.Generated.Member
@@ -236,6 +243,8 @@
return "FLAG_SUPPORTS_FILL_DIALOG";
case FLAG_IME_SHOWING:
return "FLAG_IME_SHOWING";
+ case FLAG_RESET_FILL_DIALOG_STATE:
+ return "FLAG_RESET_FILL_DIALOG_STATE";
default: return Integer.toHexString(value);
}
}
@@ -312,7 +321,8 @@
| FLAG_PASSWORD_INPUT_TYPE
| FLAG_VIEW_NOT_FOCUSED
| FLAG_SUPPORTS_FILL_DIALOG
- | FLAG_IME_SHOWING);
+ | FLAG_IME_SHOWING
+ | FLAG_RESET_FILL_DIALOG_STATE);
this.mInlineSuggestionsRequest = inlineSuggestionsRequest;
this.mDelayedFillIntentSender = delayedFillIntentSender;
@@ -473,7 +483,8 @@
| FLAG_PASSWORD_INPUT_TYPE
| FLAG_VIEW_NOT_FOCUSED
| FLAG_SUPPORTS_FILL_DIALOG
- | FLAG_IME_SHOWING);
+ | FLAG_IME_SHOWING
+ | FLAG_RESET_FILL_DIALOG_STATE);
this.mInlineSuggestionsRequest = inlineSuggestionsRequest;
this.mDelayedFillIntentSender = delayedFillIntentSender;
@@ -495,10 +506,10 @@
};
@DataClass.Generated(
- time = 1647856966565L,
+ time = 1663290803064L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/service/autofill/FillRequest.java",
- inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_SUPPORTS_FILL_DIALOG\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_IME_SHOWING\npublic static final int INVALID_REQUEST_ID\nprivate final int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate final @android.annotation.Nullable android.content.IntentSender mDelayedFillIntentSender\nprivate void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
+ inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_SUPPORTS_FILL_DIALOG\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_IME_SHOWING\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_RESET_FILL_DIALOG_STATE\npublic static final int INVALID_REQUEST_ID\nprivate final int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate final @android.annotation.Nullable android.content.IntentSender mDelayedFillIntentSender\nprivate void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/service/controls/ControlsProviderService.java b/core/java/android/service/controls/ControlsProviderService.java
index 9396a88..950c8ac 100644
--- a/core/java/android/service/controls/ControlsProviderService.java
+++ b/core/java/android/service/controls/ControlsProviderService.java
@@ -78,7 +78,7 @@
* @hide
*/
public static final String EXTRA_LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS =
- "android.service.controls.EXTRA_LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS";
+ "android.service.controls.extra.EXTRA_LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS";
/**
* @hide
diff --git a/core/java/android/service/quicksettings/IQSService.aidl b/core/java/android/service/quicksettings/IQSService.aidl
index d03ff93..7b690ea 100644
--- a/core/java/android/service/quicksettings/IQSService.aidl
+++ b/core/java/android/service/quicksettings/IQSService.aidl
@@ -15,6 +15,7 @@
*/
package android.service.quicksettings;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.graphics.drawable.Icon;
import android.service.quicksettings.Tile;
@@ -29,10 +30,10 @@
String contentDescription);
void onShowDialog(in IBinder tile);
void onStartActivity(in IBinder tile);
+ void startActivity(in IBinder tile, in PendingIntent pendingIntent);
boolean isLocked();
boolean isSecure();
void startUnlockAndRun(in IBinder tile);
-
void onDialogHidden(in IBinder tile);
void onStartSuccessful(in IBinder tile);
}
diff --git a/core/java/android/service/quicksettings/Tile.java b/core/java/android/service/quicksettings/Tile.java
index 40c0ac0..289b0e0 100644
--- a/core/java/android/service/quicksettings/Tile.java
+++ b/core/java/android/service/quicksettings/Tile.java
@@ -16,6 +16,7 @@
package android.service.quicksettings;
import android.annotation.Nullable;
+import android.app.PendingIntent;
import android.graphics.drawable.Icon;
import android.os.IBinder;
import android.os.Parcel;
@@ -39,8 +40,8 @@
/**
* An unavailable state indicates that for some reason this tile is not currently
- * available to the user for some reason, and will have no click action. The tile's
- * icon will be tinted differently to reflect this state.
+ * available to the user, and will have no click action. The tile's icon will be
+ * tinted differently to reflect this state.
*/
public static final int STATE_UNAVAILABLE = 0;
@@ -66,6 +67,7 @@
private CharSequence mSubtitle;
private CharSequence mContentDescription;
private CharSequence mStateDescription;
+ private PendingIntent mPendingIntent;
// Default to inactive until clients of the new API can update.
private int mState = STATE_INACTIVE;
@@ -223,6 +225,34 @@
}
}
+ /**
+ * Gets the Activity {@link PendingIntent} to be launched when the tile is clicked.
+ * @hide
+ */
+ @Nullable
+ public PendingIntent getActivityLaunchForClick() {
+ return mPendingIntent;
+ }
+
+ /**
+ * Sets an Activity {@link PendingIntent} to be launched when the tile is clicked.
+ *
+ * The last value set here will be launched when the user clicks in the tile, instead of
+ * forwarding the `onClick` message to the {@link TileService}. Set to {@code null} to handle
+ * the `onClick` in the `TileService`
+ * (This is the default behavior if this method is never called.)
+ * @param pendingIntent a PendingIntent for an activity to be launched onclick, or {@code null}
+ * to handle the clicks in the `TileService`.
+ * @hide
+ */
+ public void setActivityLaunchForClick(@Nullable PendingIntent pendingIntent) {
+ if (pendingIntent != null && !pendingIntent.isActivity()) {
+ throw new IllegalArgumentException();
+ } else {
+ mPendingIntent = pendingIntent;
+ }
+ }
+
@Override
public void writeToParcel(Parcel dest, int flags) {
if (mIcon != null) {
@@ -231,6 +261,12 @@
} else {
dest.writeByte((byte) 0);
}
+ if (mPendingIntent != null) {
+ dest.writeByte((byte) 1);
+ mPendingIntent.writeToParcel(dest, flags);
+ } else {
+ dest.writeByte((byte) 0);
+ }
dest.writeInt(mState);
TextUtils.writeToParcel(mLabel, dest, flags);
TextUtils.writeToParcel(mSubtitle, dest, flags);
@@ -244,6 +280,11 @@
} else {
mIcon = null;
}
+ if (source.readByte() != 0) {
+ mPendingIntent = PendingIntent.CREATOR.createFromParcel(source);
+ } else {
+ mPendingIntent = null;
+ }
mState = source.readInt();
mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
mSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 8550219..506b3b8 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -20,6 +20,7 @@
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.Dialog;
+import android.app.PendingIntent;
import android.app.Service;
import android.app.StatusBarManager;
import android.content.ComponentName;
@@ -336,6 +337,20 @@
}
/**
+ * Starts an {@link android.app.Activity}.
+ * Will collapse Quick Settings after launching.
+ *
+ * @param pendingIntent A PendingIntent for an Activity to be launched immediately.
+ * @hide
+ */
+ public void startActivityAndCollapse(PendingIntent pendingIntent) {
+ try {
+ mService.startActivity(mTileToken, pendingIntent);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
* Gets the {@link Tile} for this service.
* <p/>
* This tile may be used to get or set the current state for this
diff --git a/core/java/android/service/voice/HotwordAudioStream.java b/core/java/android/service/voice/HotwordAudioStream.java
index 5442860..86468b5 100644
--- a/core/java/android/service/voice/HotwordAudioStream.java
+++ b/core/java/android/service/voice/HotwordAudioStream.java
@@ -27,6 +27,7 @@
import android.os.Parcelable;
import android.os.PersistableBundle;
+import java.util.Arrays;
import java.util.Objects;
/**
@@ -37,6 +38,21 @@
public final class HotwordAudioStream implements Parcelable {
/**
+ * Key for int value to be read from {@link #getMetadata()}. The value is read by the system and
+ * is the length (in bytes) of the byte buffers created to copy bytes in the
+ * {@link #getAudioStreamParcelFileDescriptor()} written by the {@link HotwordDetectionService}.
+ * The buffer length should be chosen such that no additional latency is introduced. Typically,
+ * this should be <em>at least</em> the size of byte chunks written by the
+ * {@link HotwordDetectionService}.
+ *
+ * <p>If no value specified in the metadata for the buffer length, or if the value is less than
+ * 1, or if it is greater than 65,536, or if it is not an int, the default value of 2,560 will
+ * be used.</p>
+ */
+ public static final String KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES =
+ "android.service.voice.key.AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES";
+
+ /**
* The {@link AudioFormat} of the audio stream.
*/
@NonNull
@@ -44,8 +60,17 @@
private final AudioFormat mAudioFormat;
/**
- * This stream starts with the audio bytes used for hotword detection, but continues streaming
- * the audio until the stream is shutdown by the {@link HotwordDetectionService}.
+ * This stream typically starts with the audio bytes used for hotword detection, but continues
+ * streaming the audio (e.g., with the query) until the stream is shutdown by the
+ * {@link HotwordDetectionService}. The data format is expected to match
+ * {@link #getAudioFormat()}.
+ *
+ * <p>
+ * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()}
+ * to pass the start of the audio instead of streaming it here. This may prevent added latency
+ * caused by the streaming buffer (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not
+ * being large enough to handle this initial chunk of audio.
+ * </p>
*/
@NonNull
@UnsupportedAppUsage
@@ -124,13 +149,40 @@
}
/**
+ * The start of the audio used for hotword detection. The data format is expected to match
+ * {@link #getAudioFormat()}.
+ *
+ * <p>
+ * The {@link HotwordDetectionService} may use this instead of using
+ * {@link #getAudioStreamParcelFileDescriptor()} to stream these initial bytes of audio. This
+ * may prevent added latency caused by the streaming buffer (see
+ * {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle this
+ * initial chunk of audio.
+ * </p>
+ */
+ @NonNull
+ @UnsupportedAppUsage
+ private final byte[] mInitialAudio;
+
+ private static final byte[] DEFAULT_INITIAL_EMPTY_AUDIO = {};
+
+ private static byte[] defaultInitialAudio() {
+ return DEFAULT_INITIAL_EMPTY_AUDIO;
+ }
+
+ private String initialAudioToString() {
+ return "length=" + mInitialAudio.length;
+ }
+
+ /**
* Provides an instance of {@link Builder} with state corresponding to this instance.
* @hide
*/
public Builder buildUpon() {
return new Builder(mAudioFormat, mAudioStreamParcelFileDescriptor)
.setTimestamp(mTimestamp)
- .setMetadata(mMetadata);
+ .setMetadata(mMetadata)
+ .setInitialAudio(mInitialAudio);
}
/* package-private */
@@ -138,7 +190,8 @@
@NonNull AudioFormat audioFormat,
@NonNull ParcelFileDescriptor audioStreamParcelFileDescriptor,
@Nullable AudioTimestamp timestamp,
- @NonNull PersistableBundle metadata) {
+ @NonNull PersistableBundle metadata,
+ @NonNull byte[] initialAudio) {
this.mAudioFormat = audioFormat;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mAudioFormat);
@@ -149,6 +202,9 @@
this.mMetadata = metadata;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mMetadata);
+ this.mInitialAudio = initialAudio;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mInitialAudio);
// onConstructed(); // You can define this method to get a callback
}
@@ -163,8 +219,17 @@
}
/**
- * This stream starts with the audio bytes used for hotword detection, but continues streaming
- * the audio until the stream is shutdown by the {@link HotwordDetectionService}.
+ * This stream typically starts with the audio bytes used for hotword detection, but continues
+ * streaming the audio (e.g., with the query) until the stream is shutdown by the
+ * {@link HotwordDetectionService}. The data format is expected to match
+ * {@link #getAudioFormat()}.
+ *
+ * <p>
+ * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()}
+ * to pass the start of the audio instead of streaming it here. This may prevent added latency
+ * caused by the streaming buffer (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not
+ * being large enough to handle this initial chunk of audio.
+ * </p>
*/
@UnsupportedAppUsage
@NonNull
@@ -205,6 +270,24 @@
return mMetadata;
}
+ /**
+ * The start of the audio used for hotword detection. The data format is expected to match
+ * {@link #getAudioFormat()}.
+ *
+ * <p>
+ * The {@link HotwordDetectionService} may use this instead of using
+ * {@link #getAudioStreamParcelFileDescriptor()} to stream these initial bytes of audio. This
+ * may prevent added latency caused by the streaming buffer (see
+ * {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle this
+ * initial chunk of audio.
+ * </p>
+ */
+ @UnsupportedAppUsage
+ @NonNull
+ public byte[] getInitialAudio() {
+ return mInitialAudio;
+ }
+
@Override
public String toString() {
// You can override field toString logic by defining methods like:
@@ -214,7 +297,8 @@
+ "audioFormat = " + mAudioFormat + ", "
+ "audioStreamParcelFileDescriptor = " + mAudioStreamParcelFileDescriptor + ", "
+ "timestamp = " + timestampToString() + ", "
- + "metadata = " + mMetadata + " }";
+ + "metadata = " + mMetadata + ", "
+ + "initialAudio = " + initialAudioToString() + " }";
}
@Override
@@ -232,7 +316,8 @@
&& Objects.equals(mAudioStreamParcelFileDescriptor,
that.mAudioStreamParcelFileDescriptor)
&& Objects.equals(mTimestamp, that.mTimestamp)
- && Objects.equals(mMetadata, that.mMetadata);
+ && Objects.equals(mMetadata, that.mMetadata)
+ && Arrays.equals(mInitialAudio, that.mInitialAudio);
}
@Override
@@ -245,6 +330,7 @@
_hash = 31 * _hash + Objects.hashCode(mAudioStreamParcelFileDescriptor);
_hash = 31 * _hash + Objects.hashCode(mTimestamp);
_hash = 31 * _hash + Objects.hashCode(mMetadata);
+ _hash = 31 * _hash + Arrays.hashCode(mInitialAudio);
return _hash;
}
@@ -260,6 +346,7 @@
dest.writeTypedObject(mAudioStreamParcelFileDescriptor, flags);
parcelTimestamp(dest, flags);
dest.writeTypedObject(mMetadata, flags);
+ dest.writeByteArray(mInitialAudio);
}
@Override
@@ -281,6 +368,7 @@
AudioTimestamp timestamp = unparcelTimestamp(in);
PersistableBundle metadata = (PersistableBundle) in.readTypedObject(
PersistableBundle.CREATOR);
+ byte[] initialAudio = in.createByteArray();
this.mAudioFormat = audioFormat;
com.android.internal.util.AnnotationValidations.validate(
@@ -292,6 +380,9 @@
this.mMetadata = metadata;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mMetadata);
+ this.mInitialAudio = initialAudio;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mInitialAudio);
// onConstructed(); // You can define this method to get a callback
}
@@ -324,17 +415,29 @@
private AudioTimestamp mTimestamp;
@NonNull
private PersistableBundle mMetadata;
+ @NonNull
+ private byte[] mInitialAudio;
private long mBuilderFieldsSet = 0L;
/**
* Creates a new Builder.
*
- * @param audioFormat The {@link AudioFormat} of the audio stream.
- * @param audioStreamParcelFileDescriptor This stream starts with the audio bytes used for
- * hotword detection, but continues streaming
- * the audio until the stream is shutdown by the
- * {@link HotwordDetectionService}.
+ * @param audioFormat
+ * The {@link AudioFormat} of the audio stream.
+ * @param audioStreamParcelFileDescriptor
+ * This stream typically starts with the audio bytes used for hotword detection, but
+ * continues streaming the audio (e.g., with the query) until the stream is shutdown by
+ * the {@link HotwordDetectionService}. The data format is expected to match
+ * {@link #getAudioFormat()}.
+ *
+ * <p>
+ * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()}
+ * to pass the start of the audio instead of streaming it here. This may prevent added
+ * latency caused by the streaming buffer
+ * (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to
+ * handle this initial chunk of audio.
+ * </p>
*/
@UnsupportedAppUsage
public Builder(
@@ -361,9 +464,18 @@
}
/**
- * This stream starts with the audio bytes used for hotword detection, but continues
- * streaming
- * the audio until the stream is shutdown by the {@link HotwordDetectionService}.
+ * This stream typically starts with the audio bytes used for hotword detection, but
+ * continues streaming the audio (e.g., with the query) until the stream is shutdown by the
+ * {@link HotwordDetectionService}. The data format is expected to match
+ * {@link #getAudioFormat()}.
+ *
+ * <p>
+ * Alternatively, the {@link HotwordDetectionService} may use {@link #getInitialAudio()}
+ * to pass the start of the audio instead of streaming it here. This may prevent added
+ * latency caused by the streaming buffer
+ * (see {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle
+ * this initial chunk of audio.
+ * </p>
*/
@UnsupportedAppUsage
@NonNull
@@ -413,12 +525,33 @@
return this;
}
+ /**
+ * The start of the audio used for hotword detection. The data format is expected to match
+ * {@link #getAudioFormat()}.
+ *
+ * <p>
+ * The {@link HotwordDetectionService} may use this instead of using
+ * {@link #getAudioStreamParcelFileDescriptor()} to stream these initial bytes of audio.
+ * This may prevent added latency caused by the streaming buffer (see
+ * {@link #KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES}) not being large enough to handle this
+ * initial chunk of audio.
+ * </p>
+ */
+ @UnsupportedAppUsage
+ @NonNull
+ public Builder setInitialAudio(@NonNull byte[] value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x10;
+ mInitialAudio = value;
+ return this;
+ }
+
/** Builds the instance. This builder should not be touched after calling this! */
@UnsupportedAppUsage
@NonNull
public HotwordAudioStream build() {
checkNotUsed();
- mBuilderFieldsSet |= 0x10; // Mark builder used
+ mBuilderFieldsSet |= 0x20; // Mark builder used
if ((mBuilderFieldsSet & 0x4) == 0) {
mTimestamp = defaultTimestamp();
@@ -426,16 +559,20 @@
if ((mBuilderFieldsSet & 0x8) == 0) {
mMetadata = defaultMetadata();
}
+ if ((mBuilderFieldsSet & 0x10) == 0) {
+ mInitialAudio = defaultInitialAudio();
+ }
HotwordAudioStream o = new HotwordAudioStream(
mAudioFormat,
mAudioStreamParcelFileDescriptor,
mTimestamp,
- mMetadata);
+ mMetadata,
+ mInitialAudio);
return o;
}
private void checkNotUsed() {
- if ((mBuilderFieldsSet & 0x10) != 0) {
+ if ((mBuilderFieldsSet & 0x20) != 0) {
throw new IllegalStateException(
"This Builder should not be reused. Use a new Builder instance instead");
}
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index 93d4def..1a00acf 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -42,7 +42,7 @@
@UnsupportedAppUsage
oneway void destroy();
oneway void setZoomOut(float scale);
- oneway void scalePreview(in Rect positionInWindow);
+ oneway void resizePreview(in Rect positionInWindow);
oneway void removeLocalColorsAreas(in List<RectF> regions);
oneway void addLocalColorsAreas(in List<RectF> regions);
SurfaceControl mirrorSurfaceControl();
diff --git a/core/java/android/service/wallpaper/OWNERS b/core/java/android/service/wallpaper/OWNERS
index 756eef8..71bd190 100644
--- a/core/java/android/service/wallpaper/OWNERS
+++ b/core/java/android/service/wallpaper/OWNERS
@@ -3,3 +3,6 @@
dupin@google.com
dsandler@android.com
dsandler@google.com
+pomini@google.com
+poultney@google.com
+santie@google.com
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 2175859..2d1a41e 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -163,7 +163,7 @@
private static final int MSG_TOUCH_EVENT = 10040;
private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
private static final int MSG_ZOOM = 10100;
- private static final int MSG_SCALE_PREVIEW = 10110;
+ private static final int MSG_RESIZE_PREVIEW = 10110;
private static final int MSG_REPORT_SHOWN = 10150;
private static final int MSG_UPDATE_DIMMING = 10200;
private static final List<Float> PROHIBITED_STEPS = Arrays.asList(0f, Float.POSITIVE_INFINITY,
@@ -323,7 +323,7 @@
@Override
public void setFixedSize(int width, int height) {
- if (!mFixedSizeAllowed) {
+ if (!mFixedSizeAllowed && !mIWallpaperEngine.mIsPreview) {
// Regular apps can't do this. It can only work for
// certain designs of window animations, so you can't
// rely on it.
@@ -1372,16 +1372,9 @@
}
}
- private void scalePreview(Rect position) {
- if (isPreview() && mPreviewSurfacePosition == null && position != null
- || mPreviewSurfacePosition != null
- && !mPreviewSurfacePosition.equals(position)) {
- mPreviewSurfacePosition = position;
- if (mSurfaceControl.isValid()) {
- reposition();
- } else {
- updateSurface(false, false, false);
- }
+ private void resizePreview(Rect position) {
+ if (position != null) {
+ mSurfaceHolder.setFixedSize(position.width(), position.height());
}
}
@@ -2295,8 +2288,8 @@
mCaller.sendMessage(msg);
}
- public void scalePreview(Rect position) {
- Message msg = mCaller.obtainMessageO(MSG_SCALE_PREVIEW, position);
+ public void resizePreview(Rect position) {
+ Message msg = mCaller.obtainMessageO(MSG_RESIZE_PREVIEW, position);
mCaller.sendMessage(msg);
}
@@ -2383,8 +2376,8 @@
case MSG_UPDATE_DIMMING:
mEngine.updateWallpaperDimming(Float.intBitsToFloat(message.arg1));
break;
- case MSG_SCALE_PREVIEW:
- mEngine.scalePreview((Rect) message.obj);
+ case MSG_RESIZE_PREVIEW:
+ mEngine.resizePreview((Rect) message.obj);
break;
case MSG_VISIBILITY_CHANGED:
if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c0183ad..af07023 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1417,7 +1417,11 @@
mFirstPostImeInputStage = earlyPostImeStage;
mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix;
- AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
+ if (!mRemoved || !mAppVisible) {
+ AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
+ } else if (LOCAL_LOGV) {
+ Log.v(mTag, "setView() enabling visibility when removed");
+ }
}
}
}
@@ -1755,7 +1759,12 @@
if (!mAppVisible) {
WindowManagerGlobal.trimForeground();
}
- AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
+ // Only enable if the window is not already removed (via earlier call to doDie())
+ if (!mRemoved || !mAppVisible) {
+ AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
+ } else if (LOCAL_LOGV) {
+ Log.v(mTag, "handleAppVisibility() enabling visibility when removed");
+ }
}
}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 7d7270d..79c3839 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -19,6 +19,7 @@
import static android.service.autofill.FillRequest.FLAG_IME_SHOWING;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
+import static android.service.autofill.FillRequest.FLAG_RESET_FILL_DIALOG_STATE;
import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG;
import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED;
import static android.view.ContentInfo.SOURCE_AUTOFILL;
@@ -715,7 +716,7 @@
* Autofill will automatically trigger a fill request after activity
* start if there is any field is autofillable. But if there is a field that
* triggered autofill, it is unnecessary to trigger again through
- * AutofillManager#notifyViewEnteredForActivityStarted.
+ * AutofillManager#notifyViewEnteredForFillDialog.
*/
private AtomicBoolean mIsFillRequested;
@@ -728,6 +729,10 @@
private final String[] mFillDialogEnabledHints;
+ // Tracked all views that have appeared, including views that there are no
+ // dataset in responses. Used to avoid request pre-fill request again and again.
+ private final ArraySet<AutofillId> mAllTrackedViews = new ArraySet<>();
+
/** @hide */
public interface AutofillClient {
/**
@@ -1173,6 +1178,16 @@
* @hide
*/
public void notifyViewEnteredForFillDialog(View v) {
+ synchronized (mLock) {
+ if (mTrackedViews != null) {
+ // To support the fill dialog can show for the autofillable Views in
+ // different pages but in the same Activity. We need to reset the
+ // mIsFillRequested flag to allow asking for a new FillRequest when
+ // user switches to other page
+ mTrackedViews.checkViewState(v.getAutofillId());
+ }
+ }
+
// Skip if the fill request has been performed for a view.
if (mIsFillRequested.get()) {
return;
@@ -1299,6 +1314,10 @@
}
mForAugmentedAutofillOnly = false;
}
+
+ if ((flags & FLAG_SUPPORTS_FILL_DIALOG) != 0) {
+ flags |= FLAG_RESET_FILL_DIALOG_STATE;
+ }
updateSessionLocked(id, null, value, ACTION_VIEW_ENTERED, flags);
}
addEnteredIdLocked(id);
@@ -2165,6 +2184,7 @@
mIsFillRequested.set(false);
mShowAutofillDialogCalled = false;
mFillDialogTriggerIds = null;
+ mAllTrackedViews.clear();
if (resetEnteredIds) {
mEnteredIds = null;
}
@@ -2702,14 +2722,9 @@
+ ", mFillableIds=" + mFillableIds
+ ", mEnabled=" + mEnabled
+ ", mSessionId=" + mSessionId);
-
}
+
if (mEnabled && mSessionId == sessionId) {
- if (saveOnAllViewsInvisible) {
- mTrackedViews = new TrackedViews(trackedIds);
- } else {
- mTrackedViews = null;
- }
mSaveOnFinish = saveOnFinish;
if (fillableIds != null) {
if (mFillableIds == null) {
@@ -2731,6 +2746,27 @@
mSaveTriggerId = saveTriggerId;
setNotifyOnClickLocked(mSaveTriggerId, true);
}
+
+ if (!saveOnAllViewsInvisible) {
+ trackedIds = null;
+ }
+
+ final ArraySet<AutofillId> allFillableIds = new ArraySet<>();
+ if (mFillableIds != null) {
+ allFillableIds.addAll(mFillableIds);
+ }
+ if (trackedIds != null) {
+ for (AutofillId id : trackedIds) {
+ id.resetSessionId();
+ allFillableIds.add(id);
+ }
+ }
+
+ if (!allFillableIds.isEmpty()) {
+ mTrackedViews = new TrackedViews(trackedIds, Helper.toArray(allFillableIds));
+ } else {
+ mTrackedViews = null;
+ }
}
}
}
@@ -3502,10 +3538,19 @@
*/
private class TrackedViews {
/** Visible tracked views */
- @Nullable private ArraySet<AutofillId> mVisibleTrackedIds;
+ @NonNull private final ArraySet<AutofillId> mVisibleTrackedIds;
/** Invisible tracked views */
- @Nullable private ArraySet<AutofillId> mInvisibleTrackedIds;
+ @NonNull private final ArraySet<AutofillId> mInvisibleTrackedIds;
+
+ /** Visible tracked views for fill dialog */
+ @NonNull private final ArraySet<AutofillId> mVisibleDialogTrackedIds;
+
+ /** Invisible tracked views for fill dialog */
+ @NonNull private final ArraySet<AutofillId> mInvisibleDialogTrackedIds;
+
+ boolean mHasNewTrackedView;
+ boolean mIsTrackedSaveView;
/**
* Check if set is null or value is in set.
@@ -3571,43 +3616,65 @@
*
* @param trackedIds The views to be tracked
*/
- TrackedViews(@Nullable AutofillId[] trackedIds) {
- final AutofillClient client = getClient();
- if (!ArrayUtils.isEmpty(trackedIds) && client != null) {
- final boolean[] isVisible;
+ TrackedViews(@Nullable AutofillId[] trackedIds, @Nullable AutofillId[] allTrackedIds) {
+ mVisibleTrackedIds = new ArraySet<>();
+ mInvisibleTrackedIds = new ArraySet<>();
+ if (!ArrayUtils.isEmpty(trackedIds)) {
+ mIsTrackedSaveView = true;
+ initialTrackedViews(trackedIds, mVisibleTrackedIds, mInvisibleTrackedIds);
+ }
- if (client.autofillClientIsVisibleForAutofill()) {
- if (sVerbose) Log.v(TAG, "client is visible, check tracked ids");
- isVisible = client.autofillClientGetViewVisibility(trackedIds);
- } else {
- // All false
- isVisible = new boolean[trackedIds.length];
- }
-
- final int numIds = trackedIds.length;
- for (int i = 0; i < numIds; i++) {
- final AutofillId id = trackedIds[i];
- id.resetSessionId();
-
- if (isVisible[i]) {
- mVisibleTrackedIds = addToSet(mVisibleTrackedIds, id);
- } else {
- mInvisibleTrackedIds = addToSet(mInvisibleTrackedIds, id);
- }
- }
+ mVisibleDialogTrackedIds = new ArraySet<>();
+ mInvisibleDialogTrackedIds = new ArraySet<>();
+ if (!ArrayUtils.isEmpty(allTrackedIds)) {
+ initialTrackedViews(allTrackedIds, mVisibleDialogTrackedIds,
+ mInvisibleDialogTrackedIds);
+ mAllTrackedViews.addAll(Arrays.asList(allTrackedIds));
}
if (sVerbose) {
Log.v(TAG, "TrackedViews(trackedIds=" + Arrays.toString(trackedIds) + "): "
+ " mVisibleTrackedIds=" + mVisibleTrackedIds
- + " mInvisibleTrackedIds=" + mInvisibleTrackedIds);
+ + " mInvisibleTrackedIds=" + mInvisibleTrackedIds
+ + " allTrackedIds=" + Arrays.toString(allTrackedIds)
+ + " mVisibleDialogTrackedIds=" + mVisibleDialogTrackedIds
+ + " mInvisibleDialogTrackedIds=" + mInvisibleDialogTrackedIds);
}
- if (mVisibleTrackedIds == null) {
+ if (mIsTrackedSaveView && mVisibleTrackedIds.isEmpty()) {
finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
}
}
+ private void initialTrackedViews(AutofillId[] trackedIds,
+ @NonNull ArraySet<AutofillId> visibleSet,
+ @NonNull ArraySet<AutofillId> invisibleSet) {
+ final boolean[] isVisible;
+ final AutofillClient client = getClient();
+ if (ArrayUtils.isEmpty(trackedIds) || client == null) {
+ return;
+ }
+ if (client.autofillClientIsVisibleForAutofill()) {
+ if (sVerbose) Log.v(TAG, "client is visible, check tracked ids");
+ isVisible = client.autofillClientGetViewVisibility(trackedIds);
+ } else {
+ // All false
+ isVisible = new boolean[trackedIds.length];
+ }
+
+ final int numIds = trackedIds.length;
+ for (int i = 0; i < numIds; i++) {
+ final AutofillId id = trackedIds[i];
+ id.resetSessionId();
+
+ if (isVisible[i]) {
+ addToSet(visibleSet, id);
+ } else {
+ addToSet(invisibleSet, id);
+ }
+ }
+ }
+
/**
* Called when a {@link View view's} visibility changes.
*
@@ -3624,22 +3691,37 @@
if (isClientVisibleForAutofillLocked()) {
if (isVisible) {
if (isInSet(mInvisibleTrackedIds, id)) {
- mInvisibleTrackedIds = removeFromSet(mInvisibleTrackedIds, id);
- mVisibleTrackedIds = addToSet(mVisibleTrackedIds, id);
+ removeFromSet(mInvisibleTrackedIds, id);
+ addToSet(mVisibleTrackedIds, id);
+ }
+ if (isInSet(mInvisibleDialogTrackedIds, id)) {
+ removeFromSet(mInvisibleDialogTrackedIds, id);
+ addToSet(mVisibleDialogTrackedIds, id);
}
} else {
if (isInSet(mVisibleTrackedIds, id)) {
- mVisibleTrackedIds = removeFromSet(mVisibleTrackedIds, id);
- mInvisibleTrackedIds = addToSet(mInvisibleTrackedIds, id);
+ removeFromSet(mVisibleTrackedIds, id);
+ addToSet(mInvisibleTrackedIds, id);
+ }
+ if (isInSet(mVisibleDialogTrackedIds, id)) {
+ removeFromSet(mVisibleDialogTrackedIds, id);
+ addToSet(mInvisibleDialogTrackedIds, id);
}
}
}
- if (mVisibleTrackedIds == null) {
+ if (mIsTrackedSaveView && mVisibleTrackedIds.isEmpty()) {
if (sVerbose) {
Log.v(TAG, "No more visible ids. Invisible = " + mInvisibleTrackedIds);
}
finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
+
+ }
+ if (mVisibleDialogTrackedIds.isEmpty()) {
+ if (sVerbose) {
+ Log.v(TAG, "No more visible ids. Invisible = " + mInvisibleDialogTrackedIds);
+ }
+ processNoVisibleTrackedAllViews();
}
}
@@ -3653,66 +3735,66 @@
// The visibility of the views might have changed while the client was not be visible,
// hence update the visibility state for all views.
AutofillClient client = getClient();
- ArraySet<AutofillId> updatedVisibleTrackedIds = null;
- ArraySet<AutofillId> updatedInvisibleTrackedIds = null;
if (client != null) {
if (sVerbose) {
Log.v(TAG, "onVisibleForAutofillChangedLocked(): inv= " + mInvisibleTrackedIds
+ " vis=" + mVisibleTrackedIds);
}
- if (mInvisibleTrackedIds != null) {
- final ArrayList<AutofillId> orderedInvisibleIds =
- new ArrayList<>(mInvisibleTrackedIds);
- final boolean[] isVisible = client.autofillClientGetViewVisibility(
- Helper.toArray(orderedInvisibleIds));
- final int numInvisibleTrackedIds = orderedInvisibleIds.size();
- for (int i = 0; i < numInvisibleTrackedIds; i++) {
- final AutofillId id = orderedInvisibleIds.get(i);
- if (isVisible[i]) {
- updatedVisibleTrackedIds = addToSet(updatedVisibleTrackedIds, id);
-
- if (sDebug) {
- Log.d(TAG, "onVisibleForAutofill() " + id + " became visible");
- }
- } else {
- updatedInvisibleTrackedIds = addToSet(updatedInvisibleTrackedIds, id);
- }
- }
- }
-
- if (mVisibleTrackedIds != null) {
- final ArrayList<AutofillId> orderedVisibleIds =
- new ArrayList<>(mVisibleTrackedIds);
- final boolean[] isVisible = client.autofillClientGetViewVisibility(
- Helper.toArray(orderedVisibleIds));
-
- final int numVisibleTrackedIds = orderedVisibleIds.size();
- for (int i = 0; i < numVisibleTrackedIds; i++) {
- final AutofillId id = orderedVisibleIds.get(i);
-
- if (isVisible[i]) {
- updatedVisibleTrackedIds = addToSet(updatedVisibleTrackedIds, id);
- } else {
- updatedInvisibleTrackedIds = addToSet(updatedInvisibleTrackedIds, id);
-
- if (sDebug) {
- Log.d(TAG, "onVisibleForAutofill() " + id + " became invisible");
- }
- }
- }
- }
-
- mInvisibleTrackedIds = updatedInvisibleTrackedIds;
- mVisibleTrackedIds = updatedVisibleTrackedIds;
+ onVisibleForAutofillChangedInternalLocked(mVisibleTrackedIds, mInvisibleTrackedIds);
+ onVisibleForAutofillChangedInternalLocked(
+ mVisibleDialogTrackedIds, mInvisibleDialogTrackedIds);
}
- if (mVisibleTrackedIds == null) {
+ if (mIsTrackedSaveView && mVisibleTrackedIds.isEmpty()) {
if (sVerbose) {
- Log.v(TAG, "onVisibleForAutofillChangedLocked(): no more visible ids");
+ Log.v(TAG, "onVisibleForAutofillChangedLocked(): no more visible ids");
}
finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
}
+ if (mVisibleDialogTrackedIds.isEmpty()) {
+ if (sVerbose) {
+ Log.v(TAG, "onVisibleForAutofillChangedLocked(): no more visible ids");
+ }
+ processNoVisibleTrackedAllViews();
+ }
+ }
+
+ void onVisibleForAutofillChangedInternalLocked(@NonNull ArraySet<AutofillId> visibleSet,
+ @NonNull ArraySet<AutofillId> invisibleSet) {
+ // The visibility of the views might have changed while the client was not be visible,
+ // hence update the visibility state for all views.
+ if (sVerbose) {
+ Log.v(TAG, "onVisibleForAutofillChangedLocked(): inv= " + invisibleSet
+ + " vis=" + visibleSet);
+ }
+
+ ArraySet<AutofillId> allTrackedIds = new ArraySet<>();
+ allTrackedIds.addAll(visibleSet);
+ allTrackedIds.addAll(invisibleSet);
+ if (!allTrackedIds.isEmpty()) {
+ visibleSet.clear();
+ invisibleSet.clear();
+ initialTrackedViews(Helper.toArray(allTrackedIds), visibleSet, invisibleSet);
+ }
+ }
+
+ private void processNoVisibleTrackedAllViews() {
+ mShowAutofillDialogCalled = false;
+ }
+
+ void checkViewState(AutofillId id) {
+ if (mAllTrackedViews.contains(id)) {
+ return;
+ }
+ // Add the id as tracked to avoid triggering fill request again and again.
+ mAllTrackedViews.add(id);
+ if (mHasNewTrackedView) {
+ return;
+ }
+ // First one new tracks view
+ mIsFillRequested.set(false);
+ mHasNewTrackedView = true;
}
}
diff --git a/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl b/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl
index 6e40988..46f78e2 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl
@@ -31,6 +31,8 @@
/**
* Called when a voice session window is shown/hidden.
+ * Caution that there could be duplicated visibility change callbacks, it's up to the listener
+ * to dedup those events.
*/
void onVoiceSessionWindowVisibilityChanged(boolean visible);
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 8fcb6d5..afb526a 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -37,12 +37,17 @@
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__UNKNOWN_ACTION;
+import static com.android.internal.util.LatencyTracker.ActionProperties.ENABLE_SUFFIX;
+import static com.android.internal.util.LatencyTracker.ActionProperties.LEGACY_TRACE_THRESHOLD_SUFFIX;
+import static com.android.internal.util.LatencyTracker.ActionProperties.SAMPLE_INTERVAL_SUFFIX;
+import static com.android.internal.util.LatencyTracker.ActionProperties.TRACE_THRESHOLD_SUFFIX;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.os.Build;
+import android.os.ConditionVariable;
import android.os.SystemClock;
import android.os.Trace;
import android.provider.DeviceConfig;
@@ -58,6 +63,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Locale;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
@@ -261,11 +267,11 @@
@GuardedBy("mLock")
private final SparseArray<Session> mSessions = new SparseArray<>();
@GuardedBy("mLock")
- private final int[] mTraceThresholdPerAction = new int[ACTIONS_ALL.length];
- @GuardedBy("mLock")
- private int mSamplingInterval;
+ private final SparseArray<ActionProperties> mActionPropertiesMap = new SparseArray<>();
@GuardedBy("mLock")
private boolean mEnabled;
+ @VisibleForTesting
+ public final ConditionVariable mDeviceConfigPropertiesUpdated = new ConditionVariable();
public static LatencyTracker getInstance(Context context) {
if (sLatencyTracker == null) {
@@ -278,9 +284,9 @@
return sLatencyTracker;
}
- private LatencyTracker() {
+ @VisibleForTesting
+ public LatencyTracker() {
mEnabled = DEFAULT_ENABLED;
- mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
// Post initialization to the background in case we're running on the main thread.
BackgroundThread.getHandler().post(() -> this.updateProperties(
@@ -291,14 +297,24 @@
private void updateProperties(DeviceConfig.Properties properties) {
synchronized (mLock) {
- mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY,
+ int samplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY,
DEFAULT_SAMPLING_INTERVAL);
mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
for (int action : ACTIONS_ALL) {
- mTraceThresholdPerAction[action] =
- properties.getInt(getNameOfAction(STATSD_ACTION[action]), -1);
+ String actionName = getNameOfAction(STATSD_ACTION[action]).toLowerCase(Locale.ROOT);
+ int legacyActionTraceThreshold = properties.getInt(
+ actionName + LEGACY_TRACE_THRESHOLD_SUFFIX, -1);
+ mActionPropertiesMap.put(action, new ActionProperties(action,
+ properties.getBoolean(actionName + ENABLE_SUFFIX, mEnabled),
+ properties.getInt(actionName + SAMPLE_INTERVAL_SUFFIX, samplingInterval),
+ properties.getInt(actionName + TRACE_THRESHOLD_SUFFIX,
+ legacyActionTraceThreshold)));
+ }
+ if (DEBUG) {
+ Log.d(TAG, "updated action properties: " + mActionPropertiesMap);
}
}
+ mDeviceConfigPropertiesUpdated.open();
}
/**
@@ -369,16 +385,38 @@
return "com.android.telemetry.latency-tracker-" + getNameOfAction(STATSD_ACTION[action]);
}
+ /**
+ * @deprecated Use {@link #isEnabled(Context, int)}
+ */
+ @Deprecated
public static boolean isEnabled(Context ctx) {
return getInstance(ctx).isEnabled();
}
+ /**
+ * @deprecated Used {@link #isEnabled(int)}
+ */
+ @Deprecated
public boolean isEnabled() {
synchronized (mLock) {
return mEnabled;
}
}
+ public static boolean isEnabled(Context ctx, int action) {
+ return getInstance(ctx).isEnabled(action);
+ }
+
+ public boolean isEnabled(int action) {
+ synchronized (mLock) {
+ ActionProperties actionProperties = mActionPropertiesMap.get(action);
+ if (actionProperties != null) {
+ return actionProperties.isEnabled();
+ }
+ return false;
+ }
+ }
+
/**
* Notifies that an action is starting. <s>This needs to be called from the main thread.</s>
*
@@ -468,8 +506,14 @@
boolean shouldSample;
int traceThreshold;
synchronized (mLock) {
- shouldSample = ThreadLocalRandom.current().nextInt() % mSamplingInterval == 0;
- traceThreshold = mTraceThresholdPerAction[action];
+ ActionProperties actionProperties = mActionPropertiesMap.get(action);
+ if (actionProperties == null) {
+ return;
+ }
+ int nextRandNum = ThreadLocalRandom.current().nextInt(
+ actionProperties.getSamplingInterval());
+ shouldSample = nextRandNum == 0;
+ traceThreshold = actionProperties.getTraceThreshold();
}
if (traceThreshold > 0 && duration >= traceThreshold) {
@@ -549,4 +593,59 @@
return (int) (mEndRtc - mStartRtc);
}
}
+
+ @VisibleForTesting
+ static class ActionProperties {
+ static final String ENABLE_SUFFIX = "_enable";
+ static final String SAMPLE_INTERVAL_SUFFIX = "_sample_interval";
+ // TODO: migrate all usages of the legacy trace theshold property
+ static final String LEGACY_TRACE_THRESHOLD_SUFFIX = "";
+ static final String TRACE_THRESHOLD_SUFFIX = "_trace_threshold";
+
+ @Action
+ private final int mAction;
+ private final boolean mEnabled;
+ private final int mSamplingInterval;
+ private final int mTraceThreshold;
+
+ ActionProperties(
+ @Action int action,
+ boolean enabled,
+ int samplingInterval,
+ int traceThreshold) {
+ this.mAction = action;
+ com.android.internal.util.AnnotationValidations.validate(
+ Action.class, null, mAction);
+ this.mEnabled = enabled;
+ this.mSamplingInterval = samplingInterval;
+ this.mTraceThreshold = traceThreshold;
+ }
+
+ @Action
+ int getAction() {
+ return mAction;
+ }
+
+ boolean isEnabled() {
+ return mEnabled;
+ }
+
+ int getSamplingInterval() {
+ return mSamplingInterval;
+ }
+
+ int getTraceThreshold() {
+ return mTraceThreshold;
+ }
+
+ @Override
+ public String toString() {
+ return "ActionProperties{"
+ + " mAction=" + mAction
+ + ", mEnabled=" + mEnabled
+ + ", mSamplingInterval=" + mSamplingInterval
+ + ", mTraceThreshold=" + mTraceThreshold
+ + "}";
+ }
+ }
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 1235b60..2dfe893 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1522,7 +1522,8 @@
STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
STRONG_AUTH_REQUIRED_AFTER_TIMEOUT,
STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN,
- STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT})
+ STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT,
+ SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED})
@Retention(RetentionPolicy.SOURCE)
public @interface StrongAuthFlags {}
@@ -1575,11 +1576,18 @@
public static final int STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT = 0x80;
/**
+ * Some authentication is required because the trustagent either timed out or was disabled
+ * manually.
+ */
+ public static final int SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED = 0x100;
+
+ /**
* Strong auth flags that do not prevent biometric methods from being accepted as auth.
* If any other flags are set, biometric authentication is disabled.
*/
private static final int ALLOWING_BIOMETRIC = STRONG_AUTH_NOT_REQUIRED
- | SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
+ | SOME_AUTH_REQUIRED_AFTER_USER_REQUEST
+ | SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED;
private final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
private final H mHandler;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7787b7c..d83e40c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -6100,7 +6100,7 @@
<!-- @SystemApi Allows to access all app shortcuts.
@hide -->
<permission android:name="android.permission.ACCESS_SHORTCUTS"
- android:protectionLevel="signature|role" />
+ android:protectionLevel="signature|role|recents" />
<!-- @SystemApi Allows unlimited calls to shortcut mutation APIs.
@hide -->
diff --git a/core/res/res/layout/notification_material_action_list.xml b/core/res/res/layout/notification_material_action_list.xml
index a5608af..7aef82a 100644
--- a/core/res/res/layout/notification_material_action_list.xml
+++ b/core/res/res/layout/notification_material_action_list.xml
@@ -27,6 +27,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
+ android:layout_gravity="bottom"
android:orientation="horizontal"
android:background="@color/notification_action_list_background_color"
>
diff --git a/core/res/res/values-b+sr+Latn-television/strings.xml b/core/res/res/values-b+sr+Latn-television/strings.xml
index df5d8ea..8643593 100644
--- a/core/res/res/values-b+sr+Latn-television/strings.xml
+++ b/core/res/res/values-b+sr+Latn-television/strings.xml
@@ -17,6 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="7002619958660406548">"Mikrofon je blokiran"</string>
- <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="2131954635322568179">"Kamera je blokirana"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="7002619958660406548">"Микрофон је блокиран"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="2131954635322568179">"Камера је блокирана"</string>
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index c183da8..f606c8f2c 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -27,805 +27,805 @@
<string name="terabyteShort" msgid="1822367128583886496">"TB"</string>
<string name="petabyteShort" msgid="5651571254228534832">"PB"</string>
<string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
- <string name="untitled" msgid="3381766946944136678">"<Bez imena>"</string>
- <string name="emptyPhoneNumber" msgid="5812172618020360048">"(Nema broja telefona)"</string>
- <string name="unknownName" msgid="7078697621109055330">"Nepoznato"</string>
- <string name="defaultVoiceMailAlphaTag" msgid="2190754495304236490">"Glasovna pošta"</string>
+ <string name="untitled" msgid="3381766946944136678">"<Без имена>"</string>
+ <string name="emptyPhoneNumber" msgid="5812172618020360048">"(Нема броја телефона)"</string>
+ <string name="unknownName" msgid="7078697621109055330">"Непознато"</string>
+ <string name="defaultVoiceMailAlphaTag" msgid="2190754495304236490">"Гласовна пошта"</string>
<string name="defaultMsisdnAlphaTag" msgid="2285034592902077488">"MSISDN1"</string>
- <string name="mmiError" msgid="2862759606579822246">"Problemi sa vezom ili nevažeći MMI kôd."</string>
- <string name="mmiErrorNotSupported" msgid="5001803469335286099">"Funkcija nije podržana."</string>
- <string name="mmiFdnError" msgid="3975490266767565852">"Rad je ograničen samo na brojeve fiksnog biranja."</string>
- <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"Ne možete da promenite podešavanja preusmeravanja poziva sa telefona dok ste u romingu."</string>
- <string name="serviceEnabled" msgid="7549025003394765639">"Usluga je omogućena."</string>
- <string name="serviceEnabledFor" msgid="1463104778656711613">"Usluga je omogućena za:"</string>
- <string name="serviceDisabled" msgid="641878791205871379">"Usluga je onemogućena."</string>
- <string name="serviceRegistered" msgid="3856192211729577482">"Registracija je uspela."</string>
- <string name="serviceErased" msgid="997354043770513494">"Brisanje je dovršeno."</string>
- <string name="passwordIncorrect" msgid="917087532676155877">"Neispravna lozinka."</string>
- <string name="mmiComplete" msgid="6341884570892520140">"MMI kôd je izvršen."</string>
- <string name="badPin" msgid="888372071306274355">"Stari PIN koji ste uneli nije tačan."</string>
- <string name="badPuk" msgid="4232069163733147376">"PUK koji ste uneli nije tačan."</string>
- <string name="mismatchPin" msgid="2929611853228707473">"PIN kodovi koje ste uneli se ne podudaraju."</string>
- <string name="invalidPin" msgid="7542498253319440408">"Otkucajte PIN koji ima od 4 do 8 brojeva."</string>
- <string name="invalidPuk" msgid="8831151490931907083">"Unesite PUK koji se sastoji od 8 cifara ili više."</string>
- <string name="needPuk" msgid="7321876090152422918">"SIM kartica je zaključana PUK kodom. Unesite PUK kôd da biste je otključali."</string>
- <string name="needPuk2" msgid="7032612093451537186">"Unesite PUK2 da biste odblokirali SIM karticu."</string>
- <string name="enablePin" msgid="2543771964137091212">"Nije uspelo. Omogućite zaključavanje SIM/RUIM kartice."</string>
+ <string name="mmiError" msgid="2862759606579822246">"Проблеми са везом или неважећи MMI кôд."</string>
+ <string name="mmiErrorNotSupported" msgid="5001803469335286099">"Функција није подржана."</string>
+ <string name="mmiFdnError" msgid="3975490266767565852">"Рад је ограничен само на бројеве фиксног бирања."</string>
+ <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"Не можете да промените подешавања преусмеравања позива са телефона док сте у ромингу."</string>
+ <string name="serviceEnabled" msgid="7549025003394765639">"Услуга је омогућена."</string>
+ <string name="serviceEnabledFor" msgid="1463104778656711613">"Услуга је омогућена за:"</string>
+ <string name="serviceDisabled" msgid="641878791205871379">"Услуга је онемогућена."</string>
+ <string name="serviceRegistered" msgid="3856192211729577482">"Регистрација је успела."</string>
+ <string name="serviceErased" msgid="997354043770513494">"Брисање је довршено."</string>
+ <string name="passwordIncorrect" msgid="917087532676155877">"Неисправна лозинка."</string>
+ <string name="mmiComplete" msgid="6341884570892520140">"MMI кôд је извршен."</string>
+ <string name="badPin" msgid="888372071306274355">"Стари PIN који сте унели није тачан."</string>
+ <string name="badPuk" msgid="4232069163733147376">"PUK који сте унели није тачан."</string>
+ <string name="mismatchPin" msgid="2929611853228707473">"PIN кодови које сте унели се не подударају."</string>
+ <string name="invalidPin" msgid="7542498253319440408">"Откуцајте PIN који има од 4 до 8 бројева."</string>
+ <string name="invalidPuk" msgid="8831151490931907083">"Унесите PUK који се састоји од 8 цифара или више."</string>
+ <string name="needPuk" msgid="7321876090152422918">"SIM картица је закључана PUK кодом. Унесите PUK кôд да бисте је откључали."</string>
+ <string name="needPuk2" msgid="7032612093451537186">"Унесите PUK2 да бисте одблокирали SIM картицу."</string>
+ <string name="enablePin" msgid="2543771964137091212">"Није успело. Омогућите закључавање SIM/RUIM картице."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
- <item quantity="one">Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj pre nego što se SIM kartica zaključa.</item>
- <item quantity="few">Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja pre nego što se SIM kartica zaključa.</item>
- <item quantity="other">Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja pre nego što se SIM kartica zaključa.</item>
+ <item quantity="one">Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушај пре него што се SIM картица закључа.</item>
+ <item quantity="few">Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја пре него што се SIM картица закључа.</item>
+ <item quantity="other">Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја пре него што се SIM картица закључа.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"IMEI"</string>
<string name="meid" msgid="3291227361605924674">"MEID"</string>
- <string name="ClipMmi" msgid="4110549342447630629">"Dolazni ID pozivaoca"</string>
- <string name="ClirMmi" msgid="6752346475055446417">"Sakrijte ID odlaznog pozivaoca"</string>
- <string name="ColpMmi" msgid="4736462893284419302">"ID povezane linije"</string>
- <string name="ColrMmi" msgid="5889782479745764278">"Ograničenje ID-a povezane linije"</string>
- <string name="CfMmi" msgid="8390012691099787178">"Preusmeravanje poziva"</string>
- <string name="CwMmi" msgid="3164609577675404761">"Poziv na čekanju"</string>
- <string name="BaMmi" msgid="7205614070543372167">"Ograničavanje poziva"</string>
- <string name="PwdMmi" msgid="3360991257288638281">"Promena lozinke"</string>
- <string name="PinMmi" msgid="7133542099618330959">"Promena PIN koda"</string>
- <string name="CnipMmi" msgid="4897531155968151160">"Pozivanje postojećeg broja"</string>
- <string name="CnirMmi" msgid="885292039284503036">"Pozivanje broja je ograničeno"</string>
- <string name="ThreeWCMmi" msgid="2436550866139999411">"Trosmerno pozivanje"</string>
- <string name="RuacMmi" msgid="1876047385848991110">"Odbijanje nepoželjnih poziva"</string>
- <string name="CndMmi" msgid="185136449405618437">"Isporuka broja za pozivanje"</string>
- <string name="DndMmi" msgid="8797375819689129800">"Ne uznemiravaj"</string>
- <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID pozivaoca je podrazumevano ograničen. Sledeći poziv: ograničen."</string>
- <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID pozivaoca je podrazumevano ograničen. Sledeći poziv: Nije ograničen."</string>
- <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID pozivaoca podrazumevano nije ograničen. Sledeći poziv: ograničen."</string>
- <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"ID pozivaoca podrazumevano nije ograničen. Sledeći poziv: Nije ograničen."</string>
- <string name="serviceNotProvisioned" msgid="8289333510236766193">"Usluga nije dobavljena."</string>
- <string name="CLIRPermanent" msgid="166443681876381118">"Ne možete da promenite podešavanje ID-a korisnika."</string>
- <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Nema usluge mobilnih podataka"</string>
- <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"Hitni pozivi nisu dostupni"</string>
- <string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Nema glasovne usluge"</string>
- <string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"Nema glasovne usluge ni hitnih poziva"</string>
- <string name="RestrictedStateContent" msgid="7693575344608618926">"Privremeno isključio mobilni operater"</string>
- <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Privremeno je isključio mobilni operater za SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
- <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Povezivanje sa mobilnom mrežom nije uspelo"</string>
- <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probajte da promenite željenu mrežu. Dodirnite da biste promenili."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Ne možete da upućujete hitne pozive preko Wi‑Fi-ja"</string>
- <string name="notification_channel_network_alert" msgid="4788053066033851841">"Obaveštenja"</string>
- <string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmeravanje poziva"</string>
- <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim za hitan povratni poziv"</string>
- <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status mobilnih podataka"</string>
- <string name="notification_channel_sms" msgid="1243384981025535724">"SMS-ovi"</string>
- <string name="notification_channel_voice_mail" msgid="8457433203106654172">"Poruke govorne pošte"</string>
- <string name="notification_channel_wfc" msgid="9048240466765169038">"Pozivanje preko WiFi mreže"</string>
- <string name="notification_channel_sim" msgid="5098802350325677490">"Status SIM-a"</string>
- <string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Obaveštenja SIM kartice sa statusom „visok prioritet“"</string>
- <string name="peerTtyModeFull" msgid="337553730440832160">"Korisnik zahteva POTPUN režim TTY"</string>
- <string name="peerTtyModeHco" msgid="5626377160840915617">"Korisnik zahteva PRENOS ZVUKA za režim TTY"</string>
- <string name="peerTtyModeVco" msgid="572208600818270944">"Korisnik zahteva PRENOS GLASA za režim TTY"</string>
- <string name="peerTtyModeOff" msgid="2420380956369226583">"Korisnik zahteva ISKLJUČEN režim TTY"</string>
+ <string name="ClipMmi" msgid="4110549342447630629">"Долазни ИД позиваоца"</string>
+ <string name="ClirMmi" msgid="6752346475055446417">"Сакријте ИД одлазног позиваоца"</string>
+ <string name="ColpMmi" msgid="4736462893284419302">"ИД повезане линије"</string>
+ <string name="ColrMmi" msgid="5889782479745764278">"Ограничење ИД-а повезане линије"</string>
+ <string name="CfMmi" msgid="8390012691099787178">"Преусмеравање позива"</string>
+ <string name="CwMmi" msgid="3164609577675404761">"Позив на чекању"</string>
+ <string name="BaMmi" msgid="7205614070543372167">"Ограничавање позива"</string>
+ <string name="PwdMmi" msgid="3360991257288638281">"Промена лозинке"</string>
+ <string name="PinMmi" msgid="7133542099618330959">"Промена PIN кода"</string>
+ <string name="CnipMmi" msgid="4897531155968151160">"Позивање постојећег броја"</string>
+ <string name="CnirMmi" msgid="885292039284503036">"Позивање броја је ограничено"</string>
+ <string name="ThreeWCMmi" msgid="2436550866139999411">"Тросмерно позивање"</string>
+ <string name="RuacMmi" msgid="1876047385848991110">"Одбијање непожељних позива"</string>
+ <string name="CndMmi" msgid="185136449405618437">"Испорука броја за позивање"</string>
+ <string name="DndMmi" msgid="8797375819689129800">"Не узнемиравај"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ИД позиваоца је подразумевано ограничен. Следећи позив: ограничен."</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ИД позиваоца је подразумевано ограничен. Следећи позив: Није ограничен."</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ИД позиваоца подразумевано није ограничен. Следећи позив: ограничен."</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"ИД позиваоца подразумевано није ограничен. Следећи позив: Није ограничен."</string>
+ <string name="serviceNotProvisioned" msgid="8289333510236766193">"Услуга није добављена."</string>
+ <string name="CLIRPermanent" msgid="166443681876381118">"Не можете да промените подешавање ИД-а корисника."</string>
+ <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Нема услуге мобилних података"</string>
+ <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"Хитни позиви нису доступни"</string>
+ <string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Нема гласовне услуге"</string>
+ <string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"Нема гласовне услуге ни хитних позива"</string>
+ <string name="RestrictedStateContent" msgid="7693575344608618926">"Привремено искључио мобилни оператер"</string>
+ <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Привремено је искључио мобилни оператер за SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
+ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Повезивање са мобилном мрежом није успело"</string>
+ <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Пробајте да промените жељену мрежу. Додирните да бисте променили."</string>
+ <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Хитни позиви нису доступни"</string>
+ <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Не можете да упућујете хитне позиве преко Wi‑Fi-ја"</string>
+ <string name="notification_channel_network_alert" msgid="4788053066033851841">"Обавештења"</string>
+ <string name="notification_channel_call_forward" msgid="8230490317314272406">"Преусмеравање позива"</string>
+ <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим за хитан повратни позив"</string>
+ <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Статус мобилних података"</string>
+ <string name="notification_channel_sms" msgid="1243384981025535724">"SMS-ови"</string>
+ <string name="notification_channel_voice_mail" msgid="8457433203106654172">"Поруке говорне поште"</string>
+ <string name="notification_channel_wfc" msgid="9048240466765169038">"Позивање преко WiFi мреже"</string>
+ <string name="notification_channel_sim" msgid="5098802350325677490">"Статус SIM-а"</string>
+ <string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Обавештења SIM картице са статусом „висок приоритет“"</string>
+ <string name="peerTtyModeFull" msgid="337553730440832160">"Корисник захтева ПОТПУН режим TTY"</string>
+ <string name="peerTtyModeHco" msgid="5626377160840915617">"Корисник захтева ПРЕНОС ЗВУКА за режим TTY"</string>
+ <string name="peerTtyModeVco" msgid="572208600818270944">"Корисник захтева ПРЕНОС ГЛАСА за режим TTY"</string>
+ <string name="peerTtyModeOff" msgid="2420380956369226583">"Корисник захтева ИСКЉУЧЕН режим TTY"</string>
<string name="serviceClassVoice" msgid="2065556932043454987">"Voice"</string>
- <string name="serviceClassData" msgid="4148080018967300248">"Podaci"</string>
- <string name="serviceClassFAX" msgid="2561653371698904118">"FAKS"</string>
+ <string name="serviceClassData" msgid="4148080018967300248">"Подаци"</string>
+ <string name="serviceClassFAX" msgid="2561653371698904118">"ФАКС"</string>
<string name="serviceClassSMS" msgid="1547664561704509004">"SMS"</string>
- <string name="serviceClassDataAsync" msgid="2029856900898545984">"Asinhroni podaci"</string>
- <string name="serviceClassDataSync" msgid="7895071363569133704">"Sinhronizovano"</string>
- <string name="serviceClassPacket" msgid="1430642951399303804">"Paket"</string>
- <string name="serviceClassPAD" msgid="6850244583416306321">"PODLOGA"</string>
- <string name="roamingText0" msgid="7793257871609854208">"Indikator rominga je uključen"</string>
- <string name="roamingText1" msgid="5073028598334616445">"Indikator rominga je isključen"</string>
- <string name="roamingText2" msgid="2834048284153110598">"Treperenje indikatora rominga"</string>
- <string name="roamingText3" msgid="831690234035748988">"Izvan komšiluka"</string>
- <string name="roamingText4" msgid="2171252529065590728">"Izvan zgrade"</string>
- <string name="roamingText5" msgid="4294671587635796641">"Roming – željeni sistem"</string>
- <string name="roamingText6" msgid="5536156746637992029">"Roming – dostupni sistem"</string>
- <string name="roamingText7" msgid="1783303085512907706">"Roming – partner"</string>
- <string name="roamingText8" msgid="7774800704373721973">"Roming – premijum partner"</string>
- <string name="roamingText9" msgid="1933460020190244004">"Roming – potpuno funkcionisanje usluge"</string>
- <string name="roamingText10" msgid="7434767033595769499">"Roming – delimično funkcionisanje usluge"</string>
- <string name="roamingText11" msgid="5245687407203281407">"Baner rominga je uključen"</string>
- <string name="roamingText12" msgid="673537506362152640">"Baner rominga je isključen"</string>
- <string name="roamingTextSearching" msgid="5323235489657753486">"Pretraživanje usluge"</string>
- <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Podešavanje pozivanja preko WiFi-a nije uspelo"</string>
+ <string name="serviceClassDataAsync" msgid="2029856900898545984">"Асинхрони подаци"</string>
+ <string name="serviceClassDataSync" msgid="7895071363569133704">"Синхронизовано"</string>
+ <string name="serviceClassPacket" msgid="1430642951399303804">"Пакет"</string>
+ <string name="serviceClassPAD" msgid="6850244583416306321">"ПОДЛОГА"</string>
+ <string name="roamingText0" msgid="7793257871609854208">"Индикатор роминга је укључен"</string>
+ <string name="roamingText1" msgid="5073028598334616445">"Индикатор роминга је искључен"</string>
+ <string name="roamingText2" msgid="2834048284153110598">"Треперење индикатора роминга"</string>
+ <string name="roamingText3" msgid="831690234035748988">"Изван комшилука"</string>
+ <string name="roamingText4" msgid="2171252529065590728">"Изван зграде"</string>
+ <string name="roamingText5" msgid="4294671587635796641">"Роминг – жељени систем"</string>
+ <string name="roamingText6" msgid="5536156746637992029">"Роминг – доступни систем"</string>
+ <string name="roamingText7" msgid="1783303085512907706">"Роминг – партнер"</string>
+ <string name="roamingText8" msgid="7774800704373721973">"Роминг – премијум партнер"</string>
+ <string name="roamingText9" msgid="1933460020190244004">"Роминг – потпуно функционисање услуге"</string>
+ <string name="roamingText10" msgid="7434767033595769499">"Роминг – делимично функционисање услуге"</string>
+ <string name="roamingText11" msgid="5245687407203281407">"Банер роминга је укључен"</string>
+ <string name="roamingText12" msgid="673537506362152640">"Банер роминга је искључен"</string>
+ <string name="roamingTextSearching" msgid="5323235489657753486">"Претраживање услуге"</string>
+ <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Подешавање позивања преко WiFi-а није успело"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"Da biste upućivali pozive i slali poruke preko WiFi-a, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko WiFi-a. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"Да бисте упућивали позиве и слали поруке преко WiFi-а, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко WiFi-а. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="4795145070505729156">"Problem u vezi sa registrovanjem pozivanja preko Wi‑Fi-ja kod mobilnog operatera: <xliff:g id="CODE">%1$s</xliff:g>"</item>
+ <item msgid="4795145070505729156">"Проблем у вези са регистровањем позивања преко Wi‑Fi-ја код мобилног оператера: <xliff:g id="CODE">%1$s</xliff:g>"</item>
</string-array>
<!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
<skip />
- <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> pozivanje preko WiFi-a"</string>
- <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – pozivanje preko WiFi-a"</string>
- <string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN poziv"</string>
- <string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> позивање преко WiFi-а"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – позивање преко WiFi-а"</string>
+ <string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN позив"</string>
+ <string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN позив"</string>
<string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
- <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Pozivanje preko WiFi-a | <xliff:g id="SPN">%s</xliff:g>"</string>
+ <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Позивање преко WiFi-а | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
- <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Pozivanje preko WiFi-a"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Позивање преко WiFi-а"</string>
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
- <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Pozivanje preko WiFi-a"</string>
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Позивање преко WiFi-а"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
- <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Isključeno"</string>
- <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Pozivanje preko WiFi-a"</string>
- <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Poziv preko mobilne mreže"</string>
- <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Samo WiFi"</string>
+ <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Искључено"</string>
+ <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Позивање преко WiFi-а"</string>
+ <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Позив преко мобилне мреже"</string>
+ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Само WiFi"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> rezervni način za pozivanje"</string>
- <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> резервни начин за позивање"</string>
+ <string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
- <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> nakon <xliff:g id="TIME_DELAY">{2}</xliff:g> sekunde/i"</string>
- <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
- <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
- <string name="fcComplete" msgid="1080909484660507044">"Kôd funkcije je izvršen."</string>
- <string name="fcError" msgid="5325116502080221346">"Problemi sa vezom ili nevažeći kôd funkcije."</string>
- <string name="httpErrorOk" msgid="6206751415788256357">"Potvrdi"</string>
- <string name="httpError" msgid="3406003584150566720">"Došlo je do greške na mreži."</string>
- <string name="httpErrorLookup" msgid="3099834738227549349">"Nije moguće pronaći URL adresu"</string>
- <string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"Šema potvrda autentičnosti sajta nije podržana."</string>
- <string name="httpErrorAuth" msgid="469553140922938968">"Nije moguće potvrditi autentičnost."</string>
- <string name="httpErrorProxyAuth" msgid="7229662162030113406">"Potvrda identiteta preko proksi servera nije uspela."</string>
- <string name="httpErrorConnect" msgid="3295081579893205617">"Nije moguće povezati se sa serverom."</string>
- <string name="httpErrorIO" msgid="3860318696166314490">"Nije moguće komunicirati sa serverom. Probajte ponovo kasnije."</string>
- <string name="httpErrorTimeout" msgid="7446272815190334204">"Veza sa serverom je istekla."</string>
- <string name="httpErrorRedirectLoop" msgid="8455757777509512098">"Stranica sadrži previše veza za preusmeravanje sa servera."</string>
- <string name="httpErrorUnsupportedScheme" msgid="2664108769858966374">"Protokol nije podržan."</string>
- <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"Nije moguće uspostaviti bezbednu vezu."</string>
- <string name="httpErrorBadUrl" msgid="754447723314832538">"Stranicu nije moguće otvoriti zato što je URL adresa nevažeća."</string>
- <string name="httpErrorFile" msgid="3400658466057744084">"Nije moguće pristupiti datoteci."</string>
- <string name="httpErrorFileNotFound" msgid="5191433324871147386">"Nije moguće pronaći traženu datoteku."</string>
- <string name="httpErrorTooManyRequests" msgid="2149677715552037198">"Previše zahteva se obrađuje. Probajte ponovo kasnije."</string>
- <string name="notification_title" msgid="5783748077084481121">"Greška pri prijavljivanju za <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
- <string name="contentServiceSync" msgid="2341041749565687871">"Sinhronizacija"</string>
- <string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"Sinhronizacija nije uspela"</string>
- <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"Previše pokušaja brisanja sadržaja <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
- <string name="low_memory" product="tablet" msgid="5557552311566179924">"Memorija tableta je puna! Izbrišite neke datoteke da biste oslobodili prostor."</string>
- <string name="low_memory" product="watch" msgid="3479447988234030194">"Memorija sata je puna. Izbrišite neke datoteke da biste oslobodili prostor."</string>
- <string name="low_memory" product="tv" msgid="6663680413790323318">"Memorijski prostor na Android TV uređaju je pun. Izbrišite neke datoteke da biste oslobodili prostor."</string>
- <string name="low_memory" product="default" msgid="2539532364144025569">"Memorija telefona je puna! Izbrišite neke datoteke da biste oslobodili prostor."</string>
- <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{Instaliran je autoritet za izdavanje sertifikata}one{Instalirani su autoriteti za izdavanje sertifikata}few{Instalirani su autoriteti za izdavanje sertifikata}other{Instalirani su autoriteti za izdavanje sertifikata}}"</string>
- <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Od strane nepoznate treće strane"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Od strane administratora poslovnog profila"</string>
- <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Od strane <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
- <string name="work_profile_deleted" msgid="5891181538182009328">"Poslovni profil je izbrisan"</string>
- <string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikacija za administratore na poslovnom profilu nedostaje ili je oštećena. Zbog toga su poslovni profil i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
- <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Poslovni profil više nije dostupan na ovom uređaju"</string>
- <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše pokušaja unosa lozinke"</string>
- <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za ličnu upotrebu"</string>
- <string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja"</string>
- <string name="network_logging_notification_text" msgid="1327373071132562512">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string>
- <string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikacije mogu da pristupaju vašoj lokaciji"</string>
- <string name="location_changed_notification_text" msgid="7158423339982706912">"Obratite se IT administratoru da biste saznali više"</string>
- <string name="geofencing_service" msgid="3826902410740315456">"Usluga virtuelnog geografskog opsega"</string>
- <string name="country_detector" msgid="7023275114706088854">"Detektor zemlje"</string>
- <string name="location_service" msgid="2439187616018455546">"Usluga lokacije"</string>
- <string name="gnss_service" msgid="8907781262179951385">"GNSS usluga"</string>
- <string name="sensor_notification_service" msgid="7474531979178682676">"Usluga obaveštenja senzora"</string>
- <string name="twilight_service" msgid="8964898045693187224">"Usluga Sumrak"</string>
- <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS usluga za ažuriranje vremena"</string>
- <string name="device_policy_manager_service" msgid="5085762851388850332">"Usluga Menadžer smernica za uređaje"</string>
- <string name="music_recognition_manager_service" msgid="7481956037950276359">"Usluga Menadžer prepoznavanja muzike"</string>
- <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti obrisan"</string>
- <string name="factory_reset_message" msgid="2657049595153992213">"Ne možete da koristite ovu aplikaciju za administratore. Uređaj će sada biti obrisan.\n\nAko imate pitanja, kontaktirajte administratora organizacije."</string>
- <string name="printing_disabled_by" msgid="3517499806528864633">"Štampanje je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
- <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Uključite poslovni profil"</string>
- <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Lične aplikacije su blokirane dok ne uključite poslovni profil"</string>
- <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Lične aplikacije će biti blokirane: <xliff:g id="DATE">%1$s</xliff:g> u <xliff:g id="TIME">%2$s</xliff:g>. IT administrator ne dozvoljava da poslovni profil bude isključen duže od <xliff:g id="NUMBER">%3$d</xliff:g> dana."</string>
- <string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"Uključi"</string>
- <string name="me" msgid="6207584824693813140">"Ja"</string>
- <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Opcije za tablet"</string>
- <string name="power_dialog" product="tv" msgid="7792839006640933763">"Opcije Android TV-a"</string>
- <string name="power_dialog" product="default" msgid="1107775420270203046">"Opcije telefona"</string>
- <string name="silent_mode" msgid="8796112363642579333">"Nečujni režim"</string>
- <string name="turn_on_radio" msgid="2961717788170634233">"Uključi bežični signal"</string>
- <string name="turn_off_radio" msgid="7222573978109933360">"Isključi bežični signal"</string>
- <string name="screen_lock" msgid="2072642720826409809">"Zaključaj ekran"</string>
- <string name="power_off" msgid="4111692782492232778">"Ugasi"</string>
- <string name="silent_mode_silent" msgid="5079789070221150912">"Zvono je isključeno"</string>
- <string name="silent_mode_vibrate" msgid="8821830448369552678">"Vibracija zvona"</string>
- <string name="silent_mode_ring" msgid="6039011004781526678">"Zvono je uključeno"</string>
- <string name="reboot_to_update_title" msgid="2125818841916373708">"Android ažuriranje sistema"</string>
- <string name="reboot_to_update_prepare" msgid="6978842143587422365">"Ažuriranje se priprema…"</string>
- <string name="reboot_to_update_package" msgid="4644104795527534811">"Paket ažuriranja se obrađuje..."</string>
- <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Ponovo se pokreće..."</string>
- <string name="reboot_to_reset_title" msgid="2226229680017882787">"Resetovanje na fabrička podešavanja"</string>
- <string name="reboot_to_reset_message" msgid="3347690497972074356">"Ponovo se pokreće..."</string>
- <string name="shutdown_progress" msgid="5017145516412657345">"Isključivanje…"</string>
- <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Tablet će se isključiti."</string>
- <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Android TV uređaj će se ugasiti."</string>
- <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"Sat će se ugasiti."</string>
- <string name="shutdown_confirm" product="default" msgid="136816458966692315">"Telefon će se isključiti."</string>
- <string name="shutdown_confirm_question" msgid="796151167261608447">"Da li želite da isključite telefon?"</string>
- <string name="reboot_safemode_title" msgid="5853949122655346734">"Restartuj sistem u bezbednom režimu"</string>
- <string name="reboot_safemode_confirm" msgid="1658357874737219624">"Da li želite da ponovo pokrenete sistem u bezbednom režimu? Ovo će onemogućiti sve instalirane aplikacije nezavisnih proizvođača. One će biti vraćene kada ponovo pokrenete sistem."</string>
- <string name="recent_tasks_title" msgid="8183172372995396653">"Nedavno"</string>
- <string name="no_recent_tasks" msgid="9063946524312275906">"Nema nedavnih aplikacija."</string>
- <string name="global_actions" product="tablet" msgid="4412132498517933867">"Opcije za tablet"</string>
- <string name="global_actions" product="tv" msgid="3871763739487450369">"Opcije Android TV-a"</string>
- <string name="global_actions" product="default" msgid="6410072189971495460">"Opcije telefona"</string>
- <string name="global_action_lock" msgid="6949357274257655383">"Zaključaj ekran"</string>
- <string name="global_action_power_off" msgid="4404936470711393203">"Ugasi"</string>
- <string name="global_action_power_options" msgid="1185286119330160073">"Napajanje"</string>
- <string name="global_action_restart" msgid="4678451019561687074">"Restartuj"</string>
- <string name="global_action_emergency" msgid="1387617624177105088">"Hitan poziv"</string>
- <string name="global_action_bug_report" msgid="5127867163044170003">"Izveštaj o grešci"</string>
- <string name="global_action_logout" msgid="6093581310002476511">"Završi sesiju"</string>
- <string name="global_action_screenshot" msgid="2610053466156478564">"Snimak ekrana"</string>
- <string name="bugreport_title" msgid="8549990811777373050">"Izveštaj o grešci"</string>
- <string name="bugreport_message" msgid="5212529146119624326">"Ovim će se prikupiti informacije o trenutnom stanju uređaja kako bi bile poslate u poruci e-pošte. Od započinjanja izveštaja o grešci do trenutka za njegovo slanje proći će neko vreme; budite strpljivi."</string>
- <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv. izveštaj"</string>
- <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Koristite ovo u većini slučajeva. To vam omogućava da pratite napredak izveštaja, da unosite dodatne detalje o problemu i da snimate snimke ekrana. Verovatno će izostaviti neke manje korišćene odeljke za koje pravljenje izveštaja dugo traje."</string>
- <string name="bugreport_option_full_title" msgid="7681035745950045690">"Kompletan izveštaj"</string>
- <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Koristite ovu opciju radi minimalnih sistemskih smetnji kada uređaj ne reaguje, prespor je ili su vam potrebni svi odeljci izveštaja. Ne dozvoljava vam unos dodatnih detalja niti snimanje dodatnih snimaka ekrana."</string>
- <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Napravićemo snimak ekrana radi izveštaja o grešci za # sekundu.}one{Napravićemo snimak ekrana radi izveštaja o grešci za # sekundu.}few{Napravićemo snimak ekrana radi izveštaja o grešci za # sekunde.}other{Napravićemo snimak ekrana radi izveštaja o grešci za # sekundi.}}"</string>
- <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Ekran sa izveštajem o grešci je snimljen"</string>
- <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Snimanje ekrana sa izveštajem o grešci nije uspelo"</string>
- <string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Nečujni režim"</string>
- <string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"Zvuk je ISKLJUČEN"</string>
- <string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"Zvuk je UKLJUČEN"</string>
- <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"Režim rada u avionu"</string>
- <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"Režim rada u avionu je UKLJUČEN"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"Režim rada u avionu je ISKLJUČEN"</string>
- <string name="global_action_settings" msgid="4671878836947494217">"Podešavanja"</string>
- <string name="global_action_assist" msgid="2517047220311505805">"Pomoć"</string>
- <string name="global_action_voice_assist" msgid="6655788068555086695">"Glasovna pomoć"</string>
- <string name="global_action_lockdown" msgid="2475471405907902963">"Zaključavanje"</string>
+ <string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> након <xliff:g id="TIME_DELAY">{2}</xliff:g> секунде/и"</string>
+ <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
+ <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
+ <string name="fcComplete" msgid="1080909484660507044">"Кôд функције је извршен."</string>
+ <string name="fcError" msgid="5325116502080221346">"Проблеми са везом или неважећи кôд функције."</string>
+ <string name="httpErrorOk" msgid="6206751415788256357">"Потврди"</string>
+ <string name="httpError" msgid="3406003584150566720">"Дошло је до грешке на мрежи."</string>
+ <string name="httpErrorLookup" msgid="3099834738227549349">"Није могуће пронаћи URL адресу"</string>
+ <string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"Шема потврда аутентичности сајта није подржана."</string>
+ <string name="httpErrorAuth" msgid="469553140922938968">"Није могуће потврдити аутентичност."</string>
+ <string name="httpErrorProxyAuth" msgid="7229662162030113406">"Потврда идентитета преко прокси сервера није успела."</string>
+ <string name="httpErrorConnect" msgid="3295081579893205617">"Није могуће повезати се са сервером."</string>
+ <string name="httpErrorIO" msgid="3860318696166314490">"Није могуће комуницирати са сервером. Пробајте поново касније."</string>
+ <string name="httpErrorTimeout" msgid="7446272815190334204">"Веза са сервером је истекла."</string>
+ <string name="httpErrorRedirectLoop" msgid="8455757777509512098">"Страница садржи превише веза за преусмеравање са сервера."</string>
+ <string name="httpErrorUnsupportedScheme" msgid="2664108769858966374">"Протокол није подржан."</string>
+ <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"Није могуће успоставити безбедну везу."</string>
+ <string name="httpErrorBadUrl" msgid="754447723314832538">"Страницу није могуће отворити зато што је URL адреса неважећа."</string>
+ <string name="httpErrorFile" msgid="3400658466057744084">"Није могуће приступити датотеци."</string>
+ <string name="httpErrorFileNotFound" msgid="5191433324871147386">"Није могуће пронаћи тражену датотеку."</string>
+ <string name="httpErrorTooManyRequests" msgid="2149677715552037198">"Превише захтева се обрађује. Пробајте поново касније."</string>
+ <string name="notification_title" msgid="5783748077084481121">"Грешка при пријављивању за <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+ <string name="contentServiceSync" msgid="2341041749565687871">"Синхронизација"</string>
+ <string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"Синхронизација није успела"</string>
+ <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"Превише покушаја брисања садржаја <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
+ <string name="low_memory" product="tablet" msgid="5557552311566179924">"Меморија таблета је пуна! Избришите неке датотеке да бисте ослободили простор."</string>
+ <string name="low_memory" product="watch" msgid="3479447988234030194">"Меморија сата је пуна. Избришите неке датотеке да бисте ослободили простор."</string>
+ <string name="low_memory" product="tv" msgid="6663680413790323318">"Меморијски простор на Android TV уређају је пун. Избришите неке датотеке да бисте ослободили простор."</string>
+ <string name="low_memory" product="default" msgid="2539532364144025569">"Меморија телефона је пуна! Избришите неке датотеке да бисте ослободили простор."</string>
+ <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{Инсталиран је ауторитет за издавање сертификата}one{Инсталирани су ауторитети за издавање сертификата}few{Инсталирани су ауторитети за издавање сертификата}other{Инсталирани су ауторитети за издавање сертификата}}"</string>
+ <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Од стране непознате треће стране"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Од стране администратора пословног профила"</string>
+ <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Од стране <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
+ <string name="work_profile_deleted" msgid="5891181538182009328">"Пословни профил је избрисан"</string>
+ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Апликација за администраторе на пословном профилу недостаје или је оштећена. Због тога су пословни профил и повезани подаци избрисани. Обратите се администратору за помоћ."</string>
+ <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Пословни профил више није доступан на овом уређају"</string>
+ <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Превише покушаја уноса лозинке"</string>
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Администратор је уступио уређај за личну употребу"</string>
+ <string name="network_logging_notification_title" msgid="554983187553845004">"Уређајем се управља"</string>
+ <string name="network_logging_notification_text" msgid="1327373071132562512">"Организација управља овим уређајем и може да надгледа мрежни саобраћај. Додирните за детаље."</string>
+ <string name="location_changed_notification_title" msgid="3620158742816699316">"Апликације могу да приступају вашој локацији"</string>
+ <string name="location_changed_notification_text" msgid="7158423339982706912">"Обратите се ИТ администратору да бисте сазнали више"</string>
+ <string name="geofencing_service" msgid="3826902410740315456">"Услуга виртуелног географског опсега"</string>
+ <string name="country_detector" msgid="7023275114706088854">"Детектор земље"</string>
+ <string name="location_service" msgid="2439187616018455546">"Услуга локације"</string>
+ <string name="gnss_service" msgid="8907781262179951385">"GNSS услуга"</string>
+ <string name="sensor_notification_service" msgid="7474531979178682676">"Услуга обавештења сензора"</string>
+ <string name="twilight_service" msgid="8964898045693187224">"Услуга Сумрак"</string>
+ <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS услуга за ажурирање времена"</string>
+ <string name="device_policy_manager_service" msgid="5085762851388850332">"Услуга Менаџер смерница за уређаје"</string>
+ <string name="music_recognition_manager_service" msgid="7481956037950276359">"Услуга Менаџер препознавања музике"</string>
+ <string name="factory_reset_warning" msgid="6858705527798047809">"Уређај ће бити обрисан"</string>
+ <string name="factory_reset_message" msgid="2657049595153992213">"Не можете да користите ову апликацију за администраторе. Уређај ће сада бити обрисан.\n\nАко имате питања, контактирајте администратора организације."</string>
+ <string name="printing_disabled_by" msgid="3517499806528864633">"Штампање је онемогућила апликација <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
+ <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Укључите пословни профил"</string>
+ <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Личне апликације су блокиране док не укључите пословни профил"</string>
+ <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Личне апликације ће бити блокиране: <xliff:g id="DATE">%1$s</xliff:g> у <xliff:g id="TIME">%2$s</xliff:g>. ИТ администратор не дозвољава да пословни профил буде искључен дуже од <xliff:g id="NUMBER">%3$d</xliff:g> дана."</string>
+ <string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"Укључи"</string>
+ <string name="me" msgid="6207584824693813140">"Ја"</string>
+ <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Опције за таблет"</string>
+ <string name="power_dialog" product="tv" msgid="7792839006640933763">"Опције Android TV-а"</string>
+ <string name="power_dialog" product="default" msgid="1107775420270203046">"Опције телефона"</string>
+ <string name="silent_mode" msgid="8796112363642579333">"Нечујни режим"</string>
+ <string name="turn_on_radio" msgid="2961717788170634233">"Укључи бежични сигнал"</string>
+ <string name="turn_off_radio" msgid="7222573978109933360">"Искључи бежични сигнал"</string>
+ <string name="screen_lock" msgid="2072642720826409809">"Закључај екран"</string>
+ <string name="power_off" msgid="4111692782492232778">"Угаси"</string>
+ <string name="silent_mode_silent" msgid="5079789070221150912">"Звоно је искључено"</string>
+ <string name="silent_mode_vibrate" msgid="8821830448369552678">"Вибрација звона"</string>
+ <string name="silent_mode_ring" msgid="6039011004781526678">"Звоно је укључено"</string>
+ <string name="reboot_to_update_title" msgid="2125818841916373708">"Android ажурирање система"</string>
+ <string name="reboot_to_update_prepare" msgid="6978842143587422365">"Ажурирање се припрема…"</string>
+ <string name="reboot_to_update_package" msgid="4644104795527534811">"Пакет ажурирања се обрађује..."</string>
+ <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Поново се покреће..."</string>
+ <string name="reboot_to_reset_title" msgid="2226229680017882787">"Ресетовање на фабричка подешавања"</string>
+ <string name="reboot_to_reset_message" msgid="3347690497972074356">"Поново се покреће..."</string>
+ <string name="shutdown_progress" msgid="5017145516412657345">"Искључивање…"</string>
+ <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Таблет ће се искључити."</string>
+ <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Android TV уређај ће се угасити."</string>
+ <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"Сат ће се угасити."</string>
+ <string name="shutdown_confirm" product="default" msgid="136816458966692315">"Телефон ће се искључити."</string>
+ <string name="shutdown_confirm_question" msgid="796151167261608447">"Да ли желите да искључите телефон?"</string>
+ <string name="reboot_safemode_title" msgid="5853949122655346734">"Рестартуј систем у безбедном режиму"</string>
+ <string name="reboot_safemode_confirm" msgid="1658357874737219624">"Да ли желите да поново покренете систем у безбедном режиму? Ово ће онемогућити све инсталиране апликације независних произвођача. Оне ће бити враћене када поново покренете систем."</string>
+ <string name="recent_tasks_title" msgid="8183172372995396653">"Недавно"</string>
+ <string name="no_recent_tasks" msgid="9063946524312275906">"Нема недавних апликација."</string>
+ <string name="global_actions" product="tablet" msgid="4412132498517933867">"Опције за таблет"</string>
+ <string name="global_actions" product="tv" msgid="3871763739487450369">"Опције Android TV-а"</string>
+ <string name="global_actions" product="default" msgid="6410072189971495460">"Опције телефона"</string>
+ <string name="global_action_lock" msgid="6949357274257655383">"Закључај екран"</string>
+ <string name="global_action_power_off" msgid="4404936470711393203">"Угаси"</string>
+ <string name="global_action_power_options" msgid="1185286119330160073">"Напајање"</string>
+ <string name="global_action_restart" msgid="4678451019561687074">"Рестартуј"</string>
+ <string name="global_action_emergency" msgid="1387617624177105088">"Хитан позив"</string>
+ <string name="global_action_bug_report" msgid="5127867163044170003">"Извештај о грешци"</string>
+ <string name="global_action_logout" msgid="6093581310002476511">"Заврши сесију"</string>
+ <string name="global_action_screenshot" msgid="2610053466156478564">"Снимак екрана"</string>
+ <string name="bugreport_title" msgid="8549990811777373050">"Извештај о грешци"</string>
+ <string name="bugreport_message" msgid="5212529146119624326">"Овим ће се прикупити информације о тренутном стању уређаја како би биле послате у поруци е-поште. Од започињања извештаја о грешци до тренутка за његово слање проћи ће неко време; будите стрпљиви."</string>
+ <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактив. извештај"</string>
+ <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Користите ово у већини случајева. То вам омогућава да пратите напредак извештаја, да уносите додатне детаље о проблему и да снимате снимке екрана. Вероватно ће изоставити неке мање коришћене одељке за које прављење извештаја дуго траје."</string>
+ <string name="bugreport_option_full_title" msgid="7681035745950045690">"Комплетан извештај"</string>
+ <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Користите ову опцију ради минималних системских сметњи када уређај не реагује, преспор је или су вам потребни сви одељци извештаја. Не дозвољава вам унос додатних детаља нити снимање додатних снимака екрана."</string>
+ <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Направићемо снимак екрана ради извештаја о грешци за # секунду.}one{Направићемо снимак екрана ради извештаја о грешци за # секунду.}few{Направићемо снимак екрана ради извештаја о грешци за # секунде.}other{Направићемо снимак екрана ради извештаја о грешци за # секунди.}}"</string>
+ <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Екран са извештајем о грешци је снимљен"</string>
+ <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Снимање екрана са извештајем о грешци није успело"</string>
+ <string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Нечујни режим"</string>
+ <string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"Звук је ИСКЉУЧЕН"</string>
+ <string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"Звук је УКЉУЧЕН"</string>
+ <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"Режим рада у авиону"</string>
+ <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"Режим рада у авиону је УКЉУЧЕН"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"Режим рада у авиону је ИСКЉУЧЕН"</string>
+ <string name="global_action_settings" msgid="4671878836947494217">"Подешавања"</string>
+ <string name="global_action_assist" msgid="2517047220311505805">"Помоћ"</string>
+ <string name="global_action_voice_assist" msgid="6655788068555086695">"Гласовна помоћ"</string>
+ <string name="global_action_lockdown" msgid="2475471405907902963">"Закључавање"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <string name="notification_hidden_text" msgid="2835519769868187223">"Novo obaveštenje"</string>
- <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Virtuelna tastatura"</string>
- <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizička tastatura"</string>
- <string name="notification_channel_security" msgid="8516754650348238057">"Bezbednost"</string>
- <string name="notification_channel_car_mode" msgid="2123919247040988436">"Režim rada u automobilu"</string>
- <string name="notification_channel_account" msgid="6436294521740148173">"Status naloga"</string>
- <string name="notification_channel_developer" msgid="1691059964407549150">"Poruke za programere"</string>
- <string name="notification_channel_developer_important" msgid="7197281908918789589">"Važne poruke programera"</string>
- <string name="notification_channel_updates" msgid="7907863984825495278">"Ažuriranja"</string>
- <string name="notification_channel_network_status" msgid="2127687368725272809">"Status mreže"</string>
- <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Obaveštenja u vezi sa mrežom"</string>
- <string name="notification_channel_network_available" msgid="6083697929214165169">"Mreža je dostupna"</string>
- <string name="notification_channel_vpn" msgid="1628529026203808999">"Status VPN-a"</string>
- <string name="notification_channel_device_admin" msgid="6384932669406095506">"Obaveštenja od IT administratora"</string>
- <string name="notification_channel_alerts" msgid="5070241039583668427">"Obaveštenja"</string>
- <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Režim demonstracije za maloprodajne objekte"</string>
- <string name="notification_channel_usb" msgid="1528280969406244896">"USB veza"</string>
- <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aktivna aplikacija"</string>
- <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije koje troše bateriju"</string>
- <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Uvećanje"</string>
- <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Korišćenje Pristupačnosti"</string>
- <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string>
- <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Aplikacije (<xliff:g id="NUMBER">%1$d</xliff:g>) koriste bateriju"</string>
- <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
+ <string name="notification_hidden_text" msgid="2835519769868187223">"Ново обавештење"</string>
+ <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Виртуелна тастатура"</string>
+ <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физичка тастатура"</string>
+ <string name="notification_channel_security" msgid="8516754650348238057">"Безбедност"</string>
+ <string name="notification_channel_car_mode" msgid="2123919247040988436">"Режим рада у аутомобилу"</string>
+ <string name="notification_channel_account" msgid="6436294521740148173">"Статус налога"</string>
+ <string name="notification_channel_developer" msgid="1691059964407549150">"Поруке за програмере"</string>
+ <string name="notification_channel_developer_important" msgid="7197281908918789589">"Важне поруке програмера"</string>
+ <string name="notification_channel_updates" msgid="7907863984825495278">"Ажурирања"</string>
+ <string name="notification_channel_network_status" msgid="2127687368725272809">"Статус мреже"</string>
+ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Обавештења у вези са мрежом"</string>
+ <string name="notification_channel_network_available" msgid="6083697929214165169">"Мрежа је доступна"</string>
+ <string name="notification_channel_vpn" msgid="1628529026203808999">"Статус VPN-а"</string>
+ <string name="notification_channel_device_admin" msgid="6384932669406095506">"Обавештења од ИТ администратора"</string>
+ <string name="notification_channel_alerts" msgid="5070241039583668427">"Обавештења"</string>
+ <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Режим демонстрације за малопродајне објекте"</string>
+ <string name="notification_channel_usb" msgid="1528280969406244896">"USB веза"</string>
+ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Активна апликација"</string>
+ <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апликације које троше батерију"</string>
+ <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Увећање"</string>
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Коришћење Приступачности"</string>
+ <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерију"</string>
+ <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Апликације (<xliff:g id="NUMBER">%1$d</xliff:g>) користе батерију"</string>
+ <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Додирните за детаље о батерији и потрошњи података"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
- <string name="safeMode" msgid="8974401416068943888">"Bezbedni režim"</string>
- <string name="android_system_label" msgid="5974767339591067210">"Android sistem"</string>
- <string name="user_owner_label" msgid="8628726904184471211">"Pređi na lični profil"</string>
- <string name="managed_profile_label" msgid="7316778766973512382">"Pređi na poslovni profil"</string>
- <string name="permgrouplab_contacts" msgid="4254143639307316920">"Kontakti"</string>
- <string name="permgroupdesc_contacts" msgid="9163927941244182567">"pristupi kontaktima"</string>
- <string name="permgrouplab_location" msgid="1858277002233964394">"Lokacija"</string>
- <string name="permgroupdesc_location" msgid="1995955142118450685">"pristupi lokaciji ovog uređaja"</string>
- <string name="permgrouplab_calendar" msgid="6426860926123033230">"Kalendar"</string>
- <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupi kalendaru"</string>
+ <string name="safeMode" msgid="8974401416068943888">"Безбедни режим"</string>
+ <string name="android_system_label" msgid="5974767339591067210">"Android систем"</string>
+ <string name="user_owner_label" msgid="8628726904184471211">"Пређи на лични профил"</string>
+ <string name="managed_profile_label" msgid="7316778766973512382">"Пређи на пословни профил"</string>
+ <string name="permgrouplab_contacts" msgid="4254143639307316920">"Контакти"</string>
+ <string name="permgroupdesc_contacts" msgid="9163927941244182567">"приступи контактима"</string>
+ <string name="permgrouplab_location" msgid="1858277002233964394">"Локација"</string>
+ <string name="permgroupdesc_location" msgid="1995955142118450685">"приступи локацији овог уређаја"</string>
+ <string name="permgrouplab_calendar" msgid="6426860926123033230">"Календар"</string>
+ <string name="permgroupdesc_calendar" msgid="6762751063361489379">"приступи календару"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="5726462398070064542">"šalje i pregleda SMS poruke"</string>
- <string name="permgrouplab_storage" msgid="17339216290379241">"Fajlovi"</string>
- <string name="permgroupdesc_storage" msgid="5378659041354582769">"pristup fajlovima na uređaju"</string>
- <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muzika i zvuk"</string>
- <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"pristup muzici i audio sadržaju na uređaju"</string>
- <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Slike i video snimci"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"pristup slikama i video snimcima na uređaju"</string>
- <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snima zvuk"</string>
- <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fizičke aktivnosti"</string>
- <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"pristup fizičkim aktivnostima"</string>
- <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="7585150538459320326">"snima slike i video"</string>
- <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Uređaji u blizini"</string>
- <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"otkrivanje uređaja u blizini i povezivanje sa njima"</string>
- <string name="permgrouplab_calllog" msgid="7926834372073550288">"Evidencije poziva"</string>
- <string name="permgroupdesc_calllog" msgid="2026996642917801803">"čitanje i pisanje evidencije poziva na telefonu"</string>
- <string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="270048070781478204">"upućuje telefonske pozive i upravlja njima"</string>
- <string name="permgrouplab_sensors" msgid="9134046949784064495">"Senzori za telo"</string>
- <string name="permgroupdesc_sensors" msgid="2610631290633747752">"pristupa podacima senzora o vitalnim funkcijama"</string>
- <string name="permgrouplab_notifications" msgid="5472972361980668884">"Obaveštenja"</string>
- <string name="permgroupdesc_notifications" msgid="4608679556801506580">"prikazivanje obaveštenja"</string>
- <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"da preuzima sadržaj prozora"</string>
- <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Proverava sadržaj prozora sa kojim ostvarujete interakciju."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"da uključi Istraživanja dodirom"</string>
- <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Stavke koje dodirnete će biti izgovorene naglas, a možete da se krećete po ekranu pokretima."</string>
- <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"da prati tekst koji unosite"</string>
- <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Obuhvata lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
- <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"da upravlja uvećanjem prikaza"</string>
- <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Upravlja nivoom zumiranja prikaza i određivanjem položaja."</string>
- <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Obavljanje pokreta"</string>
- <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Može da dodiruje, lista, skuplja prikaz i obavlja druge pokrete."</string>
- <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Pokreti za otisak prsta"</string>
- <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može da registruje pokrete na senzoru za otisak prsta na uređaju."</string>
- <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Napravi snimak ekrana"</string>
- <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Može da napravi snimak ekrana."</string>
- <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili izmena statusne trake"</string>
- <string name="permdesc_statusBar" msgid="5809162768651019642">"Dozvoljava aplikaciji da onemogući statusnu traku ili da dodaje i uklanja sistemske ikone."</string>
- <string name="permlab_statusBarService" msgid="2523421018081437981">"funkcionisanje kao statusna traka"</string>
- <string name="permdesc_statusBarService" msgid="6652917399085712557">"Dozvoljava aplikaciji da funkcioniše kao statusna traka."</string>
- <string name="permlab_expandStatusBar" msgid="1184232794782141698">"proširenje/skupljanje statusne trake"</string>
- <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Dozvoljava aplikaciji da proširuje ili skuplja statusnu traku."</string>
- <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikazuje obaveštenja kao aktivnosti preko celog ekrana na zaključanom uređaju"</string>
- <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Omogućava aplikaciji da na zaključanom uređaju prikazuje obaveštenja kao aktivnosti preko celog ekrana."</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instaliranje prečica"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"da dodaju prečice na početni ekran bez intervencije korisnika."</string>
- <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deinstaliranje prečica"</string>
- <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Omogućava aplikaciji da uklanja prečice sa početnog ekrana bez intervencije korisnika."</string>
- <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"preusmeravanje odlaznih poziva"</string>
- <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Dozvoljava aplikaciji da vidi koji broj se bira pri odlaznom pozivu uz opciju da preusmeri poziv na drugi broj ili ga potpuno prekine."</string>
- <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"odgovaraj na telefonske pozive"</string>
- <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Dozvoljava aplikaciji da odgovori na dolazni telefonski poziv."</string>
- <string name="permlab_receiveSms" msgid="505961632050451881">"prijem tekstualnih poruka (SMS)"</string>
- <string name="permdesc_receiveSms" msgid="1797345626687832285">"Dozvoljava aplikaciji da prima i obrađuje SMS poruke. To znači da aplikacija može da nadgleda ili briše poruke koje se šalju uređaju, a da vam ih ne prikaže."</string>
- <string name="permlab_receiveMms" msgid="4000650116674380275">"prijem tekstualnih poruka (MMS)"</string>
- <string name="permdesc_receiveMms" msgid="958102423732219710">"Dozvoljava aplikaciji da prima i obrađuje MMS poruke. To znači da aplikacija može da nadgleda ili briše poruke koje se šalju uređaju, a da vam ih ne prikaže."</string>
- <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"Prosleđivanje poruka za mobilne uređaje na lokalitetu"</string>
- <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Dozvoljava aplikaciji da se vezuje za modul poruka za mobilne uređaje na lokalitetu da bi prosleđivala poruke za mobilne uređaje na lokalitetu onako kako su primljene. Obaveštenja poruka za mobilne uređaje na lokalitetu se na nekim lokacijama primaju kao upozorenja na hitne slučajeve. Zlonamerne aplikacije mogu da utiču na performanse ili ometaju rad uređaja kada se primi poruka o hitnom slučaju za mobilne uređaje na lokalitetu."</string>
- <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Upravljanje odlaznim pozivima"</string>
- <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Omogućava aplikaciji da vidi detalje o odlaznim pozivima na uređaju i da kontroliše te pozive."</string>
- <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"čitanje poruka info servisa"</string>
- <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Omogućava aplikaciji da čita poruke info servisa koje uređaj prima. Upozorenja info servisa se na nekim lokacijama primaju kao upozorenja na hitne slučajeve. Zlonamerne aplikacije mogu da utiču na performanse ili ometaju funkcionisanje uređaja kada se primi poruka info servisa o hitnom slučaju."</string>
- <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"čitanje prijavljenih fidova"</string>
- <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Dozvoljava aplikaciji da preuzima detalje o trenutno sinhronizovanim fidovima."</string>
- <string name="permlab_sendSms" msgid="7757368721742014252">"šalje i pregleda SMS poruke"</string>
- <string name="permdesc_sendSms" msgid="6757089798435130769">"Dozvoljava aplikaciji da šalje SMS poruke. Ovo može da dovede do neočekivanih troškova. Zlonamerne aplikacije mogu da šalju poruke bez vaše potvrde, što može da izazove troškove."</string>
- <string name="permlab_readSms" msgid="5164176626258800297">"čitanje tekstualnih poruka (SMS ili MMS)"</string>
- <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Ova aplikacija može da čita sve SMS (tekstualne) poruke koje se čuvaju na tabletu."</string>
- <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Ova aplikacija može da čita sve SMS (tekstualne) poruke koje se čuvaju na Android TV uređaju."</string>
- <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Ova aplikacija može da čita sve SMS (tekstualne) poruke koje se čuvaju na telefonu."</string>
- <string name="permlab_receiveWapPush" msgid="4223747702856929056">"prijem tekstualnih poruka (WAP)"</string>
- <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Dozvoljava aplikaciji da prima i obrađuje WAP poruke. Ova dozvola uključuje mogućnost praćenja ili brisanja poruka koje vam se šalju, a koje vam se ne prikazuju."</string>
- <string name="permlab_getTasks" msgid="7460048811831750262">"preuzimanje pokrenutih aplikacija"</string>
- <string name="permdesc_getTasks" msgid="7388138607018233726">"Dozvoljava aplikaciji da preuzima informacije o aktuelnim i nedavno pokrenutim zadacima. Ovo može da omogući aplikaciji da otkrije informacije o tome koje se aplikacije koriste na uređaju."</string>
- <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"upravljanje vlasnicima profila i uređaja"</string>
- <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"Dozvoljava aplikaciji da podesi vlasnike profila i vlasnika uređaja."</string>
- <string name="permlab_reorderTasks" msgid="7598562301992923804">"promena redosleda pokrenutih aplikacija"</string>
- <string name="permdesc_reorderTasks" msgid="8796089937352344183">"Dozvoljava aplikaciji da premešta zadatke u prvi plan i u pozadinu. Aplikacija može da radi ovo bez vašeg unosa."</string>
- <string name="permlab_enableCarMode" msgid="893019409519325311">"omogućavanje režima rada u automobilu"</string>
- <string name="permdesc_enableCarMode" msgid="56419168820473508">"Dozvoljava aplikaciji da omogući režim rada u automobilu."</string>
- <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"zatvaranje drugih aplikacija"</string>
- <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Dozvoljava aplikaciji da zaustavi pozadinske procese drugih aplikacija. Ovo može da zaustavi druge aplikacije."</string>
- <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Ova aplikacija može da se prikazuje preko drugih aplikacija"</string>
- <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Ova aplikacija može da se prikazuje preko drugih aplikacija ili drugih delova delova ekrana. To može da ometa standardno korišćenje aplikacija i način na koji se druge aplikacije prikazuju."</string>
- <string name="permlab_runInBackground" msgid="541863968571682785">"pokretanje u pozadini"</string>
- <string name="permdesc_runInBackground" msgid="4344539472115495141">"Ova aplikacija može da se pokreće u pozadini. To može brže da istroši bateriju."</string>
- <string name="permlab_useDataInBackground" msgid="783415807623038947">"korišćenje podataka u pozadini"</string>
- <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Ova aplikacija može da koristi podatke u pozadini. To može da poveća potrošnju podataka."</string>
- <string name="permlab_persistentActivity" msgid="464970041740567970">"omogućavanje neprekidne aktivnosti aplikacije"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Dozvoljava aplikaciji da učini sopstvene komponente trajnim u memoriji. Ovo može da ograniči memoriju dostupnu drugim aplikacijama i uspori tablet."</string>
- <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Dozvoljava aplikaciji da trajno zadrži neke svoje delove u memoriji. Ovo može da ograniči memoriju dostupnu drugim aplikacijama i uspori Android TV uređaj."</string>
- <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Dozvoljava aplikaciji da učini sopstvene komponente trajnim u memoriji. Ovo može da ograniči memoriju dostupnu drugim aplikacijama i uspori telefon."</string>
- <string name="permlab_foregroundService" msgid="1768855976818467491">"pokreni uslugu u prvom planu"</string>
- <string name="permdesc_foregroundService" msgid="8720071450020922795">"Dozvoljava aplikaciji da koristi usluge u prvom planu."</string>
- <string name="permlab_getPackageSize" msgid="375391550792886641">"merenje memorijskog prostora u aplikaciji"</string>
- <string name="permdesc_getPackageSize" msgid="742743530909966782">"Dozvoljava aplikaciji da preuzme veličine kôda, podataka i keša."</string>
- <string name="permlab_writeSettings" msgid="8057285063719277394">"izmena podešavanja sistema"</string>
- <string name="permdesc_writeSettings" msgid="8293047411196067188">"Dozvoljava aplikaciji da menja podatke o podešavanju sistema. Zlonamerne aplikacije mogu da oštete konfiguraciju sistema."</string>
- <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"pokretanje pri pokretanju sistema"</string>
- <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Omogućava da se aplikacija pokrene odmah nakon pokretanja sistema. To može da uspori pokretanje tableta, pri čemu ova aplikacija može da uspori funkcionisanje celog tableta time što će uvek biti aktivna."</string>
- <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Dozvoljava aplikaciji da se pokrene odmah po uključivanju sistema. To može da uspori pokretanje Android TV uređaja i aplikacija može da uspori funkcionisanje uređaja u celini tako što će uvek biti aktivna."</string>
- <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Omogućava da se aplikacija pokrene čim se sistem pokrene. To može da uspori pokretanje telefona, pri čemu ova aplikacija može da uspori funkcionisanje celog telefona time što će uvek biti aktivna."</string>
- <string name="permlab_broadcastSticky" msgid="4552241916400572230">"slanje prijemčivih emitovanja"</string>
- <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Dozvoljava aplikaciji da šalje prijemčiva emitovanja, koja ostaju po završetku emitovanja. Prekomerna upotreba može da uspori ili destabilizuje tablet tako što će ga primorati da troši previše memorije."</string>
- <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Dozvoljava aplikaciji da šalje lepljiva emitovanja koja ostaju po završetku emitovanja. Prekomerna upotreba može da uspori ili destabilizuje Android TV uređaj tako što će ga primorati da troši previše memorije."</string>
- <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Dozvoljava aplikaciji da šalje prijemčiva emitovanja, koja ostaju po završetku emitovanja. Prekomerna upotreba može da uspori ili destabilizuje telefon tako što će ga primorati da troši previše memorije."</string>
- <string name="permlab_readContacts" msgid="8776395111787429099">"čitanje kontakata"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na tabletu. Aplikacije će imati pristup i nalozima na vašem tabletu na kojima su napravljeni kontakti. Tu mogu da spadaju nalozi koje su otvorile aplikacije koje ste instalirali. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
- <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na Android TV uređaju. Aplikacije će imati pristup i nalozima na vašem Android TV uređaju na kojima su napravljeni kontakti. Tu mogu da spadaju nalozi koje su otvorile aplikacije koje ste instalirali. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
- <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na telefonu. Aplikacije će imati pristup i nalozima na vašem telefonu na kojima su napravljeni kontakti. Tu mogu da spadaju nalozi koje su otvorile aplikacije koje ste instalirali. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
- <string name="permlab_writeContacts" msgid="8919430536404830430">"izmena kontakata"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na tabletu. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na Android TV uređaju. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
- <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na telefonu. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
- <string name="permlab_readCallLog" msgid="1739990210293505948">"čitanje evidencije poziva"</string>
- <string name="permdesc_readCallLog" msgid="8964770895425873433">"Ova aplikacija može da čita istoriju poziva."</string>
- <string name="permlab_writeCallLog" msgid="670292975137658895">"pisanje evidencije poziva"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Dozvoljava aplikaciji da menja evidenciju poziva na tabletu, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamerne aplikacije mogu ovo da koriste da bi brisale ili menjale evidenciju poziva."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Dozvoljava aplikaciji da menja evidenciju poziva na Android TV uređaju, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamerne aplikacije mogu ovo da koriste za brisanje ili menjanje evidencije poziva."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Dozvoljava aplikaciji da menja evidenciju poziva na telefonu, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamerne aplikacije mogu ovo da koriste da bi brisale ili menjale evidenciju poziva."</string>
- <string name="permlab_bodySensors" msgid="662918578601619569">"Pristup podacima senzora za telo, kao što je puls, u toku korišćenja"</string>
- <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok se aplikacija koristi."</string>
- <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima senzora za telo, kao što je puls, u pozadini"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok je aplikacija u pozadini."</string>
- <string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja i podataka iz kalendara"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na tabletu, kao i da deli ili čuva podatke iz kalendara."</string>
- <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na Android TV uređaju, kao i da deli ili čuva podatke iz kalendara."</string>
- <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na telefonu, kao i da deli ili čuva podatke iz kalendara."</string>
- <string name="permlab_writeCalendar" msgid="6422137308329578076">"dodavanje ili izmena kalendarskih događaja i slanje poruka e-pošte gostima bez znanja vlasnika"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Ova aplikaciji može da dodaje, uklanja ili menja događaje iz kalendara na tabletu. Ova aplikacija može da šalje poruke koje izgledaju kao da ih šalju vlasnici kalendara ili da menja događaje bez znanja vlasnika."</string>
- <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Ova aplikacija može da dodaje, uklanja ili menja događaje iz kalendara na Android TV uređaju. Ova aplikacija može da šalje poruke koje izgledaju kao da ih šalju vlasnici kalendara ili da menja događaje bez znanja vlasnika."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Ova aplikaciji može da dodaje, uklanja ili menja događaje iz kalendara na telefonu. Ova aplikacija može da šalje poruke koje izgledaju kao da ih šalju vlasnici kalendara ili da menja događaje bez znanja vlasnika."</string>
- <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"pristup dodatnim komandama dobavljača lokacije"</string>
- <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Omogućava aplikaciji da pristupa dodatnim komandama davaoca usluga lokacije. To može da omogući aplikaciji da utiče na rad GPS-a ili drugih izvora lokacije."</string>
- <string name="permlab_accessFineLocation" msgid="6426318438195622966">"pristup preciznoj lokaciji samo u prvom planu"</string>
- <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Ova aplikacija može da odredi vašu tačnu lokaciju na osnovu usluga lokacije dok se aplikacija koristi. Usluge lokacije za uređaj moraju da budu uključene da bi aplikacija odredila lokaciju. To može da poveća potrošnju baterije."</string>
- <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"pristup približnoj lokaciji samo u prvom planu"</string>
- <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Ova aplikacija može da odredi vašu približnu lokaciju na osnovu usluga lokacije dok se aplikacija koristi. Usluge lokacije za uređaj moraju da budu uključene da bi aplikacija odredila lokaciju."</string>
- <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"pristup lokaciji u pozadini"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Ova aplikacija može da pristupa lokaciji u bilo kom trenutku, čak i dok se aplikacija ne koristi."</string>
- <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"promena audio podešavanja"</string>
- <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Dozvoljava aplikaciji da menja globalna audio podešavanja kao što su jačina zvuka i izbor zvučnika koji se koristi kao izlaz."</string>
- <string name="permlab_recordAudio" msgid="1208457423054219147">"snimanje audio zapisa"</string>
- <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ova aplikacija može da snima zvuk pomoću mikrofona dok se aplikacija koristi."</string>
- <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"da snima zvuk u pozadini"</string>
- <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ova aplikacija može da snima zvuk pomoću mikrofona u bilo kom trenutku."</string>
- <string name="permlab_sim_communication" msgid="176788115994050692">"slanje komandi na SIM"</string>
- <string name="permdesc_sim_communication" msgid="4179799296415957960">"Omogućava aplikaciji da šalje komande SIM kartici. To je veoma opasno."</string>
- <string name="permlab_activityRecognition" msgid="1782303296053990884">"prepoznavanje fizičkih aktivnosti"</string>
- <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ova aplikacija može da prepozna fizičke aktivnosti."</string>
- <string name="permlab_camera" msgid="6320282492904119413">"snimanje fotografija i video snimaka"</string>
- <string name="permdesc_camera" msgid="5240801376168647151">"Ova aplikacija može da snima slike i video snimke pomoću kamere dok se aplikacija koristi."</string>
- <string name="permlab_backgroundCamera" msgid="7549917926079731681">"da snima slike i video snimke u pozadini"</string>
- <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ova aplikacija može da snima fotografije i video snimke pomoću kamere u bilo kom trenutku."</string>
- <string name="permlab_systemCamera" msgid="3642917457796210580">"Dozvolite nekoj aplikaciji ili usluzi da pristupa kamerama sistema da bi snimala slike i video snimke"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ova privilegovana sistemska aplikacija može da snima slike i video snimke pomoću kamere sistema u bilo kom trenutku. Aplikacija treba da ima i dozvolu android.permission.CAMERA"</string>
- <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Dozvolite aplikaciji ili usluzi da dobija povratne pozive o otvaranju ili zatvaranju uređaja sa kamerom."</string>
- <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ova aplikacija može da dobija povratne pozive kada se bilo koji uređaj sa kamerom otvara ili zatvara (pomoću neke aplikacije)."</string>
- <string name="permlab_vibrate" msgid="8596800035791962017">"kontrola vibracije"</string>
- <string name="permdesc_vibrate" msgid="8733343234582083721">"Dozvoljava aplikaciji da kontroliše vibraciju."</string>
- <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Dozvoljava aplikaciji da pristupa stanju vibriranja."</string>
- <string name="permlab_callPhone" msgid="1798582257194643320">"direktno pozivanje brojeva telefona"</string>
- <string name="permdesc_callPhone" msgid="5439809516131609109">"Dozvoljava aplikaciji da poziva brojeve telefona bez vaše dozvole. Ovo može da dovede do neočekivanih troškova ili poziva. Imajte na umu da ovo ne dozvoljava aplikaciji da poziva brojeve za hitne slučajeve. Zlonamerne aplikacije mogu da pozivaju bez vaše potvrde, što može da dovede do troškova."</string>
- <string name="permlab_accessImsCallService" msgid="442192920714863782">"pristup usluzi poziva pomoću razmene trenutnih poruka"</string>
- <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Dozvoljava aplikaciji da koristi uslugu razmene trenutnih poruka da bi upućivala pozive bez vaše intervencije."</string>
- <string name="permlab_readPhoneState" msgid="8138526903259297969">"čitanje statusa i identiteta telefona"</string>
- <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Dozvoljava aplikaciji da pristupa funkcijama telefona na uređaju. Ova dozvola omogućava aplikaciji da utvrdi broj telefona i ID-ove uređaja, zatim da li je poziv aktivan, kao i broj daljinskog uređaja sa kojim je uspostavljen poziv."</string>
- <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"očitavanje osnovnog telefonskog statusa i identiteta"</string>
- <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Omogućava aplikaciji da pristupa osnovnim telefonskim funkcijama uređaja."</string>
- <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"preusmeravanje poziva preko sistema"</string>
- <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Dozvoljava aplikaciji da preusmerava pozive preko sistema da bi poboljšala doživljaj pozivanja."</string>
- <string name="permlab_callCompanionApp" msgid="3654373653014126884">"pregled i kontrola poziva preko sistema."</string>
- <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Dozvoljava aplikaciji da pregleda i kontroliše trenutne pozive na uređaju. To obuhvata informacije poput brojeva telefona i statusa poziva."</string>
- <string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"izuzimanje iz ograničenja za snimanje zvuka"</string>
- <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Izuzmite aplikaciju iz ograničenja za snimanje zvuka."</string>
- <string name="permlab_acceptHandover" msgid="2925523073573116523">"nastavi poziv u drugoj aplikaciji"</string>
- <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Dozvoljava aplikaciji da nastavi poziv koji je započet u drugoj aplikaciji."</string>
- <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"čitanje brojeva telefona"</string>
- <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Dozvoljava aplikaciji da pristupa brojevima telefona na uređaju."</string>
- <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"ne isključuj ekran u automobilu"</string>
- <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"sprečavanje prelaska tableta u stanje spavanja"</string>
- <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"sprečava Android TV uređaj da pređe u stanje spavanja"</string>
- <string name="permlab_wakeLock" product="default" msgid="569409726861695115">"sprečavanje prelaska telefona u stanje spavanja"</string>
- <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"Dozvoljava aplikaciji da ne isključuje ekran u automobilu."</string>
- <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Dozvoljava aplikaciji da spreči tablet da pređe u stanje spavanja."</string>
- <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Dozvoljava aplikaciji da spreči Android TV uređaj da pređe u stanje spavanja."</string>
- <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Dozvoljava aplikaciji da spreči telefon da pređe u stanje spavanja."</string>
- <string name="permlab_transmitIr" msgid="8077196086358004010">"prenos infracrvenih zraka"</string>
- <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Dozvoljava aplikaciji da koristi odašiljač infracrvenih zraka tableta."</string>
- <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Dozvoljava da aplikacija koristi odašiljač infracrvenih zraka na Android TV uređaju."</string>
- <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Dozvoljava aplikaciji da koristi odašiljač infracrvenih zraka telefona."</string>
- <string name="permlab_setWallpaper" msgid="6959514622698794511">"podešavanje pozadine"</string>
- <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Dozvoljava aplikaciji da postavlja pozadinu sistema."</string>
- <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"prilagođavanje veličine pozadine"</string>
- <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Dozvoljava aplikaciji da podesi savete za sistemsku veličinu pozadine."</string>
- <string name="permlab_setTimeZone" msgid="7922618798611542432">"podešavanje vremenske zone"</string>
- <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Dozvoljava aplikaciji da promeni vremensku zonu tableta."</string>
- <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Dozvoljava aplikaciji da menja vremensku zonu Android TV uređaja."</string>
- <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Dozvoljava aplikaciji da promeni vremensku zonu telefona."</string>
- <string name="permlab_getAccounts" msgid="5304317160463582791">"pronalaženje naloga na uređaju"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Dozvoljava aplikaciji da preuzima listu naloga poznatih tabletu. Ovo može da obuhvata bilo koje naloge koje prave aplikacije koje instalirate."</string>
- <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Dozvoljava aplikaciji da dođe do liste naloga poznatih Android TV uređaju. Ovo može da obuhvata sve naloge koje otvaraju aplikacije koje ste instalirali."</string>
- <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Dozvoljava aplikaciji da preuzima listu naloga poznatih telefonu. Ovo može da obuhvata bilo koje naloge koje prave aplikacije koje instalirate."</string>
- <string name="permlab_accessNetworkState" msgid="2349126720783633918">"pregled mrežnih veza"</string>
- <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Dozvoljava aplikaciji da pregleda informacije o mrežnim vezama kao što su informacije o tome koje mreže postoje i koje mreže su povezane."</string>
- <string name="permlab_createNetworkSockets" msgid="3224420491603590541">"ima pun mrežni pristup"</string>
- <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Dozvoljava aplikaciji da pravi mrežne priključke i koristi prilagođene mrežne protokole. Pregledač i druge aplikacije omogućavaju slanje podataka na Internet, pa ova dozvola nije potrebna za slanje podataka na Internet."</string>
- <string name="permlab_changeNetworkState" msgid="8945711637530425586">"promena veze sa mrežom"</string>
- <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Dozvoljava aplikaciji da menja status povezivanja sa mrežom."</string>
- <string name="permlab_changeTetherState" msgid="9079611809931863861">"promena povezivanja privezivanjem"</string>
- <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Dozvoljava aplikaciji da menja status veze sa privezanom mrežom."</string>
- <string name="permlab_accessWifiState" msgid="5552488500317911052">"pregled WiFi veza"</string>
- <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Dozvoljava aplikaciji da pregleda informacije o WiFi umrežavanju, kao što su informacije o tome da li je WiFi omogućen i nazivi povezanih WiFi uređaja."</string>
- <string name="permlab_changeWifiState" msgid="7947824109713181554">"povezivanje i prekid veze sa WiFi mrežom"</string>
- <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Dozvoljava aplikaciji da se povezuje sa pristupnim tačkama za WiFi i prekida vezu sa njima, kao i da unosi promene u konfiguraciju uređaja za WiFi mreže."</string>
- <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"omogućavanje prijema višesmernog WiFi saobraćaja"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na WiFi mreži pomoću višesmernih adresa, a ne samo na tablet. Koristi više napajanja od režima jednosmernog saobraćaja."</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na WiFi mreži pomoću višesmernih adresa, a ne samo na Android TV uređaj. Koristi više energije od režima bez višesmernog slanja."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na WiFi mreži pomoću višesmernih adresa, a ne samo na telefon. Koristi više napajanja od režima jednosmernog saobraćaja."</string>
- <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"pristup Bluetooth podešavanjima"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Dozvoljava aplikaciji da konfiguriše lokalni Bluetooth tablet, kao i da otkrije daljinske uređaje i upari se sa njima."</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Dozvoljava aplikaciji da konfiguriše Bluetooth na Android TV uređaju i da otkrije udaljene uređaje i upari se sa njima."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Dozvoljava aplikaciji da konfiguriše lokalni Bluetooth telefon, kao i da otkrije daljinske uređaje i upari se sa njima."</string>
- <string name="permlab_accessWimaxState" msgid="7029563339012437434">"povezivanje i prekid veze sa WiMAX-om"</string>
- <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Dozvoljava aplikaciji da utvrdi da li je WiMAX omogućen, kao i informacije o bilo kojim povezanim WiMAX mrežama."</string>
- <string name="permlab_changeWimaxState" msgid="6223305780806267462">"promeni WiMAX statusa"</string>
- <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Dozvoljava aplikaciji da povezuje tablet sa WiMAX mrežama i prekida veze sa njima."</string>
- <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Dozvoljava aplikaciji da povezuje Android TV uređaj sa WiMAX mrežama i da prekida tu vezu."</string>
- <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Dozvoljava aplikaciji da povezuje telefon sa WiMAX mrežama i prekida veze sa njima."</string>
- <string name="permlab_bluetooth" msgid="586333280736937209">"uparivanje sa Bluetooth uređajima"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Dozvoljava aplikaciji da pregleda konfiguraciju Bluetooth-a na tabletu, kao i da uspostavlja i prihvata veze sa uparenim uređajima."</string>
- <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Dozvoljava aplikaciji da pregleda konfiguraciju Bluetooth-a na Android TV uređaju i da uspostavlja i prihvata veze sa uparenim uređajima."</string>
- <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Dozvoljava aplikaciji da pregleda konfiguraciju Bluetooth-a na telefonu, kao i da uspostavlja i prihvata veze sa uparenim uređajima."</string>
- <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"otkrivanje i uparivanje sa obližnjim Bluetooth uređ."</string>
- <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Dozvoljava aplikaciji da otkriva Bluetooth uređaje u blizini i uparuje se sa njima"</string>
- <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezivanje sa uparenim Bluetooth uređajima"</string>
- <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Dozvoljava aplikaciji da se povezuje sa uparenim Bluetooth uređajima"</string>
- <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"oglašavanje na Bluetooth uređajima u blizini"</string>
- <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Dozvoljava aplikaciji da se oglašava na Bluetooth uređajima u blizini"</string>
- <string name="permlab_uwb_ranging" msgid="8141915781475770665">"određivanje razdaljine između uređaja ultra-širokog pojasa u blizini"</string>
- <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dozvoljava aplikaciji da određuje relativnu razdaljinu između uređaja ultra-širokog pojasa u blizini"</string>
- <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcija sa WiFi uređajima u blizini"</string>
- <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Dozvoljava aplikaciji da se oglašava, povezuje i utvrđuje relativnu poziciju WiFi uređaja u blizini"</string>
- <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o željenoj NFC usluzi za plaćanje"</string>
- <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da preuzima informacije o željenoj NFC usluzi za plaćanje, poput registrovanih identifikatora aplikacija i odredišta preusmeravanja."</string>
- <string name="permlab_nfc" msgid="1904455246837674977">"kontrola komunikacije u užem polju (Near Field Communication)"</string>
- <string name="permdesc_nfc" msgid="8352737680695296741">"Dozvoljava aplikaciji da komunicira sa oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
- <string name="permlab_disableKeyguard" msgid="3605253559020928505">"onemogućavanje zaključavanja ekrana"</string>
- <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Dozvoljava aplikaciji da onemogući zaključavanje tastature i sve povezane bezbednosne mere sa lozinkama. Na primer, telefon onemogućava zaključavanje tastature pri prijemu dolaznog telefonskog poziva, a zatim ga ponovo omogućava po završetku poziva."</string>
- <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"traženje složenosti zaključavanja ekrana"</string>
- <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Dozvoljava aplikaciji da sazna nivo složenosti zaključavanja ekrana (visoka, srednja, niska ili nijedna), što ukazuje na mogući opseg trajanja i tip zaključavanja ekrana. Aplikacija može i da predlaže korisnicima da ažuriraju zaključavanje ekrana na određeni nivo, ali korisnici slobodno mogu da zanemare to i da idu na druge stranice. Imajte na umu da se podaci za zaključavanje ekrana ne čuvaju kao običan tekst, pa aplikacija ne zna tačnu lozinku."</string>
- <string name="permlab_postNotification" msgid="4875401198597803658">"prikazivanje obaveštenja"</string>
- <string name="permdesc_postNotification" msgid="5974977162462877075">"Dozvoljava aplikaciji da prikazuje obaveštenja"</string>
- <string name="permlab_useBiometric" msgid="6314741124749633786">"koristi biometrijski hardver"</string>
- <string name="permdesc_useBiometric" msgid="7502858732677143410">"Dozvoljava aplikaciji da koristi biometrijski hardver za potvrdu identiteta"</string>
- <string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljaj hardverom za otiske prstiju"</string>
- <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Dozvoljava aplikaciji da aktivira metode za dodavanje i brisanje šablona otisaka prstiju koji će se koristiti."</string>
- <string name="permlab_useFingerprint" msgid="1001421069766751922">"koristi hardver za otiske prstiju"</string>
- <string name="permdesc_useFingerprint" msgid="412463055059323742">"Dozvoljava aplikaciji da koristi hardver za otiske prstiju radi potvrde identiteta"</string>
- <string name="permlab_audioWrite" msgid="8501705294265669405">"izmena muzičke kolekcije"</string>
- <string name="permdesc_audioWrite" msgid="8057399517013412431">"Dozvoljava aplikaciji da menja muzičku kolekciju."</string>
- <string name="permlab_videoWrite" msgid="5940738769586451318">"izmena video kolekcije"</string>
- <string name="permdesc_videoWrite" msgid="6124731210613317051">"Dozvoljava aplikaciji da menja video kolekciju."</string>
- <string name="permlab_imagesWrite" msgid="1774555086984985578">"izmena kolekcije slika"</string>
- <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Dozvoljava aplikaciji da menja kolekciju slika."</string>
- <string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz medijske kolekcije"</string>
- <string name="permdesc_mediaLocation" msgid="597912899423578138">"Dozvoljava aplikaciji da čita lokacije iz medijske kolekcije."</string>
- <string name="biometric_app_setting_name" msgid="3339209978734534457">"Koristite biometriju"</string>
- <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristite biometriju ili zaključavanje ekrana"</string>
- <string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite svoj identitet"</string>
- <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Koristite biometrijski podatak da biste nastavili"</string>
- <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Koristite biometrijski podatak ili zaključavanje ekrana da biste nastavili"</string>
- <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
- <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Potvrda identiteta je otkazana"</string>
- <string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
- <string name="biometric_error_canceled" msgid="8266582404844179778">"Potvrda identiteta je otkazana"</string>
- <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Niste podesili ni PIN, ni šablon, ni lozinku"</string>
- <string name="biometric_error_generic" msgid="6784371929985434439">"Greška pri potvrdi identiteta"</string>
- <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristite zaključavanje ekrana"</string>
- <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrebite zaključavanje ekrana da biste nastavili"</string>
- <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Jako pritisnite senzor"</string>
- <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Prepoznavanje otiska prsta nije uspelo. Probajte ponovo."</string>
- <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Obrišite senzor za otisak prsta i probajte ponovo"</string>
- <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Obrišite senzor i probajte ponovo"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Jako pritisnite senzor"</string>
- <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Previše sporo ste pomerili prst. Probajte ponovo."</string>
- <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probajte sa drugim otiskom prsta"</string>
- <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Previše je svetlo"</string>
- <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Otkriven je pritisak dugmeta za uključivanje"</string>
- <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Probajte da prilagodite"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put pomalo promenite položaj prsta"</string>
+ <string name="permgroupdesc_sms" msgid="5726462398070064542">"шаље и прегледа SMS поруке"</string>
+ <string name="permgrouplab_storage" msgid="17339216290379241">"Фајлови"</string>
+ <string name="permgroupdesc_storage" msgid="5378659041354582769">"приступ фајловима на уређају"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музика и звук"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"приступ музици и аудио садржају на уређају"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Слике и видео снимци"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"приступ сликама и видео снимцима на уређају"</string>
+ <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
+ <string name="permgroupdesc_microphone" msgid="1047786732792487722">"снима звук"</string>
+ <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физичке активности"</string>
+ <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"приступ физичким активностима"</string>
+ <string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
+ <string name="permgroupdesc_camera" msgid="7585150538459320326">"снима слике и видео"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Уређаји у близини"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"откривање уређаја у близини и повезивање са њима"</string>
+ <string name="permgrouplab_calllog" msgid="7926834372073550288">"Евиденције позива"</string>
+ <string name="permgroupdesc_calllog" msgid="2026996642917801803">"читање и писање евиденције позива на телефону"</string>
+ <string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
+ <string name="permgroupdesc_phone" msgid="270048070781478204">"упућује телефонске позиве и управља њима"</string>
+ <string name="permgrouplab_sensors" msgid="9134046949784064495">"Сензори за тело"</string>
+ <string name="permgroupdesc_sensors" msgid="2610631290633747752">"приступа подацима сензора о виталним функцијама"</string>
+ <string name="permgrouplab_notifications" msgid="5472972361980668884">"Обавештења"</string>
+ <string name="permgroupdesc_notifications" msgid="4608679556801506580">"приказивање обавештења"</string>
+ <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"да преузима садржај прозора"</string>
+ <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Проверава садржај прозора са којим остварујете интеракцију."</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"да укључи Истраживања додиром"</string>
+ <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Ставке које додирнете ће бити изговорене наглас, а можете да се крећете по екрану покретима."</string>
+ <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"да прати текст који уносите"</string>
+ <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Обухвата личне податке као што су бројеви кредитних картица и лозинке."</string>
+ <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"да управља увећањем приказа"</string>
+ <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Управља нивоом зумирања приказа и одређивањем положаја."</string>
+ <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Обављање покрета"</string>
+ <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Може да додирује, листа, скупља приказ и обавља друге покрете."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Покрети за отисак прста"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да региструје покрете на сензору за отисак прста на уређају."</string>
+ <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Направи снимак екрана"</string>
+ <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да направи снимак екрана."</string>
+ <string name="permlab_statusBar" msgid="8798267849526214017">"онемогућавање или измена статусне траке"</string>
+ <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозвољава апликацији да онемогући статусну траку или да додаје и уклања системске иконе."</string>
+ <string name="permlab_statusBarService" msgid="2523421018081437981">"функционисање као статусна трака"</string>
+ <string name="permdesc_statusBarService" msgid="6652917399085712557">"Дозвољава апликацији да функционише као статусна трака."</string>
+ <string name="permlab_expandStatusBar" msgid="1184232794782141698">"проширење/скупљање статусне траке"</string>
+ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозвољава апликацији да проширује или скупља статусну траку."</string>
+ <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"приказује обавештења као активности преко целог екрана на закључаном уређају"</string>
+ <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Омогућава апликацији да на закључаном уређају приказује обавештења као активности преко целог екрана."</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"Инсталирање пречица"</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"да додају пречице на почетни екран без интервенције корисника."</string>
+ <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталирање пречица"</string>
+ <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Омогућава апликацији да уклања пречице са почетног екрана без интервенције корисника."</string>
+ <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"преусмеравање одлазних позива"</string>
+ <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Дозвољава апликацији да види који број се бира при одлазном позиву уз опцију да преусмери позив на други број или га потпуно прекине."</string>
+ <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"одговарај на телефонске позиве"</string>
+ <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Дозвољава апликацији да одговори на долазни телефонски позив."</string>
+ <string name="permlab_receiveSms" msgid="505961632050451881">"пријем текстуалних порука (SMS)"</string>
+ <string name="permdesc_receiveSms" msgid="1797345626687832285">"Дозвољава апликацији да прима и обрађује SMS поруке. То значи да апликација може да надгледа или брише поруке које се шаљу уређају, а да вам их не прикаже."</string>
+ <string name="permlab_receiveMms" msgid="4000650116674380275">"пријем текстуалних порука (MMS)"</string>
+ <string name="permdesc_receiveMms" msgid="958102423732219710">"Дозвољава апликацији да прима и обрађује MMS поруке. То значи да апликација може да надгледа или брише поруке које се шаљу уређају, а да вам их не прикаже."</string>
+ <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"Прослеђивање порука за мобилне уређаје на локалитету"</string>
+ <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Дозвољава апликацији да се везује за модул порука за мобилне уређаје на локалитету да би прослеђивала поруке за мобилне уређаје на локалитету онако како су примљене. Обавештења порука за мобилне уређаје на локалитету се на неким локацијама примају као упозорења на хитне случајеве. Злонамерне апликације могу да утичу на перформансе или ометају рад уређаја када се прими порука о хитном случају за мобилне уређаје на локалитету."</string>
+ <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Управљање одлазним позивима"</string>
+ <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Омогућава апликацији да види детаље о одлазним позивима на уређају и да контролише те позиве."</string>
+ <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"читање порука инфо сервиса"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Омогућава апликацији да чита поруке инфо сервиса које уређај прима. Упозорења инфо сервиса се на неким локацијама примају као упозорења на хитне случајеве. Злонамерне апликације могу да утичу на перформансе или ометају функционисање уређаја када се прими порука инфо сервиса о хитном случају."</string>
+ <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"читање пријављених фидова"</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Дозвољава апликацији да преузима детаље о тренутно синхронизованим фидовима."</string>
+ <string name="permlab_sendSms" msgid="7757368721742014252">"шаље и прегледа SMS поруке"</string>
+ <string name="permdesc_sendSms" msgid="6757089798435130769">"Дозвољава апликацији да шаље SMS поруке. Ово може да доведе до неочекиваних трошкова. Злонамерне апликације могу да шаљу поруке без ваше потврде, што може да изазове трошкове."</string>
+ <string name="permlab_readSms" msgid="5164176626258800297">"читање текстуалних порука (SMS или MMS)"</string>
+ <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Ова апликација може да чита све SMS (текстуалне) поруке које се чувају на таблету."</string>
+ <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Ова апликација може да чита све SMS (текстуалне) поруке које се чувају на Android TV уређају."</string>
+ <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Ова апликација може да чита све SMS (текстуалне) поруке које се чувају на телефону."</string>
+ <string name="permlab_receiveWapPush" msgid="4223747702856929056">"пријем текстуалних порука (WAP)"</string>
+ <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Дозвољава апликацији да прима и обрађује WAP поруке. Ова дозвола укључује могућност праћења или брисања порука које вам се шаљу, а које вам се не приказују."</string>
+ <string name="permlab_getTasks" msgid="7460048811831750262">"преузимање покренутих апликација"</string>
+ <string name="permdesc_getTasks" msgid="7388138607018233726">"Дозвољава апликацији да преузима информације о актуелним и недавно покренутим задацима. Ово може да омогући апликацији да открије информације о томе које се апликације користе на уређају."</string>
+ <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"управљање власницима профила и уређаја"</string>
+ <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"Дозвољава апликацији да подеси власнике профила и власника уређаја."</string>
+ <string name="permlab_reorderTasks" msgid="7598562301992923804">"промена редоследа покренутих апликација"</string>
+ <string name="permdesc_reorderTasks" msgid="8796089937352344183">"Дозвољава апликацији да премешта задатке у први план и у позадину. Апликација може да ради ово без вашег уноса."</string>
+ <string name="permlab_enableCarMode" msgid="893019409519325311">"омогућавање режима рада у аутомобилу"</string>
+ <string name="permdesc_enableCarMode" msgid="56419168820473508">"Дозвољава апликацији да омогући режим рада у аутомобилу."</string>
+ <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"затварање других апликација"</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Дозвољава апликацији да заустави позадинске процесе других апликација. Ово може да заустави друге апликације."</string>
+ <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Ова апликација може да се приказује преко других апликација"</string>
+ <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Ова апликација може да се приказује преко других апликација или других делова делова екрана. То може да омета стандардно коришћење апликација и начин на који се друге апликације приказују."</string>
+ <string name="permlab_runInBackground" msgid="541863968571682785">"покретање у позадини"</string>
+ <string name="permdesc_runInBackground" msgid="4344539472115495141">"Ова апликација може да се покреће у позадини. То може брже да истроши батерију."</string>
+ <string name="permlab_useDataInBackground" msgid="783415807623038947">"коришћење података у позадини"</string>
+ <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Ова апликација може да користи податке у позадини. То може да повећа потрошњу података."</string>
+ <string name="permlab_persistentActivity" msgid="464970041740567970">"омогућавање непрекидне активности апликације"</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Дозвољава апликацији да учини сопствене компоненте трајним у меморији. Ово може да ограничи меморију доступну другим апликацијама и успори таблет."</string>
+ <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Дозвољава апликацији да трајно задржи неке своје делове у меморији. Ово може да ограничи меморију доступну другим апликацијама и успори Android TV уређај."</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Дозвољава апликацији да учини сопствене компоненте трајним у меморији. Ово може да ограничи меморију доступну другим апликацијама и успори телефон."</string>
+ <string name="permlab_foregroundService" msgid="1768855976818467491">"покрени услугу у првом плану"</string>
+ <string name="permdesc_foregroundService" msgid="8720071450020922795">"Дозвољава апликацији да користи услуге у првом плану."</string>
+ <string name="permlab_getPackageSize" msgid="375391550792886641">"мерење меморијског простора у апликацији"</string>
+ <string name="permdesc_getPackageSize" msgid="742743530909966782">"Дозвољава апликацији да преузме величине кôда, података и кеша."</string>
+ <string name="permlab_writeSettings" msgid="8057285063719277394">"измена подешавања система"</string>
+ <string name="permdesc_writeSettings" msgid="8293047411196067188">"Дозвољава апликацији да мења податке о подешавању система. Злонамерне апликације могу да оштете конфигурацију система."</string>
+ <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"покретање при покретању система"</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Омогућава да се апликација покрене одмах након покретања система. То може да успори покретање таблета, при чему ова апликација може да успори функционисање целог таблета тиме што ће увек бити активна."</string>
+ <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Дозвољава апликацији да се покрене одмах по укључивању система. То може да успори покретање Android TV уређаја и апликација може да успори функционисање уређаја у целини тако што ће увек бити активна."</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Омогућава да се апликација покрене чим се систем покрене. То може да успори покретање телефона, при чему ова апликација може да успори функционисање целог телефона тиме што ће увек бити активна."</string>
+ <string name="permlab_broadcastSticky" msgid="4552241916400572230">"слање пријемчивих емитовања"</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Дозвољава апликацији да шаље пријемчива емитовања, која остају по завршетку емитовања. Прекомерна употреба може да успори или дестабилизује таблет тако што ће га приморати да троши превише меморије."</string>
+ <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Дозвољава апликацији да шаље лепљива емитовања која остају по завршетку емитовања. Прекомерна употреба може да успори или дестабилизује Android TV уређај тако што ће га приморати да троши превише меморије."</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Дозвољава апликацији да шаље пријемчива емитовања, која остају по завршетку емитовања. Прекомерна употреба може да успори или дестабилизује телефон тако што ће га приморати да троши превише меморије."</string>
+ <string name="permlab_readContacts" msgid="8776395111787429099">"читање контаката"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Дозвољава апликацији да чита податке о контактима које чувате на таблету. Апликације ће имати приступ и налозима на вашем таблету на којима су направљени контакти. Ту могу да спадају налози које су отвориле апликације које сте инсталирали. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Дозвољава апликацији да чита податке о контактима које чувате на Android TV уређају. Апликације ће имати приступ и налозима на вашем Android TV уређају на којима су направљени контакти. Ту могу да спадају налози које су отвориле апликације које сте инсталирали. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Дозвољава апликацији да чита податке о контактима које чувате на телефону. Апликације ће имати приступ и налозима на вашем телефону на којима су направљени контакти. Ту могу да спадају налози које су отвориле апликације које сте инсталирали. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
+ <string name="permlab_writeContacts" msgid="8919430536404830430">"измена контаката"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Дозвољава апликацији да мења податке о контактима које чувате на таблету. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Дозвољава апликацији да мења податке о контактима које чувате на Android TV уређају. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Дозвољава апликацији да мења податке о контактима које чувате на телефону. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
+ <string name="permlab_readCallLog" msgid="1739990210293505948">"читање евиденције позива"</string>
+ <string name="permdesc_readCallLog" msgid="8964770895425873433">"Ова апликација може да чита историју позива."</string>
+ <string name="permlab_writeCallLog" msgid="670292975137658895">"писање евиденције позива"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Дозвољава апликацији да мења евиденцију позива на таблету, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Дозвољава апликацији да мења евиденцију позива на Android TV уређају, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе за брисање или мењање евиденције позива."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Дозвољава апликацији да мења евиденцију позива на телефону, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Приступ подацима сензора за тело, као што је пулс, у току коришћења"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док се апликација користи."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Приступ подацима сензора за тело, као што је пулс, у позадини"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док је апликација у позадини."</string>
+ <string name="permlab_readCalendar" msgid="6408654259475396200">"Читање догађаја и података из календара"</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ова апликација може да чита све догађаје из календара које чувате на таблету, као и да дели или чува податке из календара."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ова апликација може да чита све догађаје из календара које чувате на Android TV уређају, као и да дели или чува податке из календара."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Ова апликација може да чита све догађаје из календара које чувате на телефону, као и да дели или чува податке из календара."</string>
+ <string name="permlab_writeCalendar" msgid="6422137308329578076">"додавање или измена календарских догађаја и слање порука е-поште гостима без знања власника"</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Ова апликацији може да додаје, уклања или мења догађаје из календара на таблету. Ова апликација може да шаље поруке које изгледају као да их шаљу власници календара или да мења догађаје без знања власника."</string>
+ <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Ова апликација може да додаје, уклања или мења догађаје из календара на Android TV уређају. Ова апликација може да шаље поруке које изгледају као да их шаљу власници календара или да мења догађаје без знања власника."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Ова апликацији може да додаје, уклања или мења догађаје из календара на телефону. Ова апликација може да шаље поруке које изгледају као да их шаљу власници календара или да мења догађаје без знања власника."</string>
+ <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"приступ додатним командама добављача локације"</string>
+ <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Омогућава апликацији да приступа додатним командама даваоца услуга локације. То може да омогући апликацији да утиче на рад GPS-а или других извора локације."</string>
+ <string name="permlab_accessFineLocation" msgid="6426318438195622966">"приступ прецизној локацији само у првом плану"</string>
+ <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Ова апликација може да одреди вашу тачну локацију на основу услуга локације док се апликација користи. Услуге локације за уређај морају да буду укључене да би апликација одредила локацију. То може да повећа потрошњу батерије."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"приступ приближној локацији само у првом плану"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Ова апликација може да одреди вашу приближну локацију на основу услуга локације док се апликација користи. Услуге локације за уређај морају да буду укључене да би апликација одредила локацију."</string>
+ <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"приступ локацији у позадини"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Ова апликација може да приступа локацији у било ком тренутку, чак и док се апликација не користи."</string>
+ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"промена аудио подешавања"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Дозвољава апликацији да мења глобална аудио подешавања као што су јачина звука и избор звучника који се користи као излаз."</string>
+ <string name="permlab_recordAudio" msgid="1208457423054219147">"снимање аудио записа"</string>
+ <string name="permdesc_recordAudio" msgid="5857246765327514062">"Ова апликација може да снима звук помоћу микрофона док се апликација користи."</string>
+ <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"да снима звук у позадини"</string>
+ <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Ова апликација може да снима звук помоћу микрофона у било ком тренутку."</string>
+ <string name="permlab_sim_communication" msgid="176788115994050692">"слање команди на SIM"</string>
+ <string name="permdesc_sim_communication" msgid="4179799296415957960">"Омогућава апликацији да шаље команде SIM картици. То је веома опасно."</string>
+ <string name="permlab_activityRecognition" msgid="1782303296053990884">"препознавање физичких активности"</string>
+ <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ова апликација може да препозна физичке активности."</string>
+ <string name="permlab_camera" msgid="6320282492904119413">"снимање фотографија и видео снимака"</string>
+ <string name="permdesc_camera" msgid="5240801376168647151">"Ова апликација може да снима слике и видео снимке помоћу камере док се апликација користи."</string>
+ <string name="permlab_backgroundCamera" msgid="7549917926079731681">"да снима слике и видео снимке у позадини"</string>
+ <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ова апликација може да снима фотографије и видео снимке помоћу камере у било ком тренутку."</string>
+ <string name="permlab_systemCamera" msgid="3642917457796210580">"Дозволите некој апликацији или услузи да приступа камерама система да би снимала слике и видео снимке"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ова привилегована системска апликација може да снима слике и видео снимке помоћу камере система у било ком тренутку. Апликација треба да има и дозволу android.permission.CAMERA"</string>
+ <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Дозволите апликацији или услузи да добија повратне позиве о отварању или затварању уређаја са камером."</string>
+ <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ова апликација може да добија повратне позиве када се било који уређај са камером отвара или затвара (помоћу неке апликације)."</string>
+ <string name="permlab_vibrate" msgid="8596800035791962017">"контрола вибрације"</string>
+ <string name="permdesc_vibrate" msgid="8733343234582083721">"Дозвољава апликацији да контролише вибрацију."</string>
+ <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Дозвољава апликацији да приступа стању вибрирања."</string>
+ <string name="permlab_callPhone" msgid="1798582257194643320">"директно позивање бројева телефона"</string>
+ <string name="permdesc_callPhone" msgid="5439809516131609109">"Дозвољава апликацији да позива бројеве телефона без ваше дозволе. Ово може да доведе до неочекиваних трошкова или позива. Имајте на уму да ово не дозвољава апликацији да позива бројеве за хитне случајеве. Злонамерне апликације могу да позивају без ваше потврде, што може да доведе до трошкова."</string>
+ <string name="permlab_accessImsCallService" msgid="442192920714863782">"приступ услузи позива помоћу размене тренутних порука"</string>
+ <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Дозвољава апликацији да користи услугу размене тренутних порука да би упућивала позиве без ваше интервенције."</string>
+ <string name="permlab_readPhoneState" msgid="8138526903259297969">"читање статуса и идентитета телефона"</string>
+ <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Дозвољава апликацији да приступа функцијама телефона на уређају. Ова дозвола омогућава апликацији да утврди број телефона и ИД-ове уређаја, затим да ли је позив активан, као и број даљинског уређаја са којим је успостављен позив."</string>
+ <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"очитавање основног телефонског статуса и идентитета"</string>
+ <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Омогућава апликацији да приступа основним телефонским функцијама уређаја."</string>
+ <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"преусмеравање позива преко система"</string>
+ <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Дозвољава апликацији да преусмерава позиве преко система да би побољшала доживљај позивања."</string>
+ <string name="permlab_callCompanionApp" msgid="3654373653014126884">"преглед и контрола позива преко система."</string>
+ <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Дозвољава апликацији да прегледа и контролише тренутне позиве на уређају. То обухвата информације попут бројева телефона и статуса позива."</string>
+ <string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"изузимање из ограничења за снимање звука"</string>
+ <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Изузмите апликацију из ограничења за снимање звука."</string>
+ <string name="permlab_acceptHandover" msgid="2925523073573116523">"настави позив у другој апликацији"</string>
+ <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Дозвољава апликацији да настави позив који је започет у другој апликацији."</string>
+ <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"читање бројева телефона"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Дозвољава апликацији да приступа бројевима телефона на уређају."</string>
+ <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"не искључуј екран у аутомобилу"</string>
+ <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"спречавање преласка таблета у стање спавања"</string>
+ <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"спречава Android TV уређај да пређе у стање спавања"</string>
+ <string name="permlab_wakeLock" product="default" msgid="569409726861695115">"спречавање преласка телефона у стање спавања"</string>
+ <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"Дозвољава апликацији да не искључује екран у аутомобилу."</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Дозвољава апликацији да спречи таблет да пређе у стање спавања."</string>
+ <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Дозвољава апликацији да спречи Android TV уређај да пређе у стање спавања."</string>
+ <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Дозвољава апликацији да спречи телефон да пређе у стање спавања."</string>
+ <string name="permlab_transmitIr" msgid="8077196086358004010">"пренос инфрацрвених зрака"</string>
+ <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Дозвољава апликацији да користи одашиљач инфрацрвених зрака таблета."</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Дозвољава да апликација користи одашиљач инфрацрвених зрака на Android TV уређају."</string>
+ <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Дозвољава апликацији да користи одашиљач инфрацрвених зрака телефона."</string>
+ <string name="permlab_setWallpaper" msgid="6959514622698794511">"подешавање позадине"</string>
+ <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Дозвољава апликацији да поставља позадину система."</string>
+ <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"прилагођавање величине позадине"</string>
+ <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Дозвољава апликацији да подеси савете за системску величину позадине."</string>
+ <string name="permlab_setTimeZone" msgid="7922618798611542432">"подешавање временске зоне"</string>
+ <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Дозвољава апликацији да промени временску зону таблета."</string>
+ <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Дозвољава апликацији да мења временску зону Android TV уређаја."</string>
+ <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Дозвољава апликацији да промени временску зону телефона."</string>
+ <string name="permlab_getAccounts" msgid="5304317160463582791">"проналажење налога на уређају"</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Дозвољава апликацији да преузима листу налога познатих таблету. Ово може да обухвата било које налоге које праве апликације које инсталирате."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Дозвољава апликацији да дође до листе налога познатих Android TV уређају. Ово може да обухвата све налоге које отварају апликације које сте инсталирали."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Дозвољава апликацији да преузима листу налога познатих телефону. Ово може да обухвата било које налоге које праве апликације које инсталирате."</string>
+ <string name="permlab_accessNetworkState" msgid="2349126720783633918">"преглед мрежних веза"</string>
+ <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Дозвољава апликацији да прегледа информације о мрежним везама као што су информације о томе које мреже постоје и које мреже су повезане."</string>
+ <string name="permlab_createNetworkSockets" msgid="3224420491603590541">"има пун мрежни приступ"</string>
+ <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Дозвољава апликацији да прави мрежне прикључке и користи прилагођене мрежне протоколе. Прегледач и друге апликације омогућавају слање података на Интернет, па ова дозвола није потребна за слање података на Интернет."</string>
+ <string name="permlab_changeNetworkState" msgid="8945711637530425586">"промена везе са мрежом"</string>
+ <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Дозвољава апликацији да мења статус повезивања са мрежом."</string>
+ <string name="permlab_changeTetherState" msgid="9079611809931863861">"промена повезивања привезивањем"</string>
+ <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Дозвољава апликацији да мења статус везе са привезаном мрежом."</string>
+ <string name="permlab_accessWifiState" msgid="5552488500317911052">"преглед WiFi веза"</string>
+ <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Дозвољава апликацији да прегледа информације о WiFi умрежавању, као што су информације о томе да ли је WiFi омогућен и називи повезаних WiFi уређаја."</string>
+ <string name="permlab_changeWifiState" msgid="7947824109713181554">"повезивање и прекид везе са WiFi мрежом"</string>
+ <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Дозвољава апликацији да се повезује са приступним тачкама за WiFi и прекида везу са њима, као и да уноси промене у конфигурацију уређаја за WiFi мреже."</string>
+ <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"омогућавање пријема вишесмерног WiFi саобраћаја"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на WiFi мрежи помоћу вишесмерних адреса, а не само на таблет. Користи више напајања од режима једносмерног саобраћаја."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на WiFi мрежи помоћу вишесмерних адреса, а не само на Android TV уређај. Користи више енергије од режима без вишесмерног слања."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на WiFi мрежи помоћу вишесмерних адреса, а не само на телефон. Користи више напајања од режима једносмерног саобраћаја."</string>
+ <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"приступ Bluetooth подешавањима"</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Дозвољава апликацији да конфигурише локални Bluetooth таблет, као и да открије даљинске уређаје и упари се са њима."</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Дозвољава апликацији да конфигурише Bluetooth на Android TV уређају и да открије удаљене уређаје и упари се са њима."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Дозвољава апликацији да конфигурише локални Bluetooth телефон, као и да открије даљинске уређаје и упари се са њима."</string>
+ <string name="permlab_accessWimaxState" msgid="7029563339012437434">"повезивање и прекид везе са WiMAX-ом"</string>
+ <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Дозвољава апликацији да утврди да ли је WiMAX омогућен, као и информације о било којим повезаним WiMAX мрежама."</string>
+ <string name="permlab_changeWimaxState" msgid="6223305780806267462">"промени WiMAX статуса"</string>
+ <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Дозвољава апликацији да повезује таблет са WiMAX мрежама и прекида везе са њима."</string>
+ <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Дозвољава апликацији да повезује Android TV уређај са WiMAX мрежама и да прекида ту везу."</string>
+ <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Дозвољава апликацији да повезује телефон са WiMAX мрежама и прекида везе са њима."</string>
+ <string name="permlab_bluetooth" msgid="586333280736937209">"упаривање са Bluetooth уређајима"</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Дозвољава апликацији да прегледа конфигурацију Bluetooth-а на таблету, као и да успоставља и прихвата везе са упареним уређајима."</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Дозвољава апликацији да прегледа конфигурацију Bluetooth-а на Android TV уређају и да успоставља и прихвата везе са упареним уређајима."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Дозвољава апликацији да прегледа конфигурацију Bluetooth-а на телефону, као и да успоставља и прихвата везе са упареним уређајима."</string>
+ <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"откривање и упаривање са оближњим Bluetooth уређ."</string>
+ <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дозвољава апликацији да открива Bluetooth уређаје у близини и упарује се са њима"</string>
+ <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"повезивање са упареним Bluetooth уређајима"</string>
+ <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дозвољава апликацији да се повезује са упареним Bluetooth уређајима"</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"оглашавање на Bluetooth уређајима у близини"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Дозвољава апликацији да се оглашава на Bluetooth уређајима у близини"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"одређивање раздаљине између уређаја ултра-широког појаса у близини"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дозвољава апликацији да одређује релативну раздаљину између уређаја ултра-широког појаса у близини"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"интеракција са WiFi уређајима у близини"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Дозвољава апликацији да се оглашава, повезује и утврђује релативну позицију WiFi уређаја у близини"</string>
+ <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информације о жељеној NFC услузи за плаћање"</string>
+ <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозвољава апликацији да преузима информације о жељеној NFC услузи за плаћање, попут регистрованих идентификатора апликација и одредишта преусмеравања."</string>
+ <string name="permlab_nfc" msgid="1904455246837674977">"контрола комуникације у ужем пољу (Near Field Communication)"</string>
+ <string name="permdesc_nfc" msgid="8352737680695296741">"Дозвољава апликацији да комуницира са ознакама, картицама и читачима комуникације кратког домета (NFC)."</string>
+ <string name="permlab_disableKeyguard" msgid="3605253559020928505">"онемогућавање закључавања екрана"</string>
+ <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Дозвољава апликацији да онемогући закључавање тастатуре и све повезане безбедносне мере са лозинкама. На пример, телефон онемогућава закључавање тастатуре при пријему долазног телефонског позива, а затим га поново омогућава по завршетку позива."</string>
+ <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"тражење сложености закључавања екрана"</string>
+ <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозвољава апликацији да сазна ниво сложености закључавања екрана (висока, средња, ниска или ниједна), што указује на могући опсег трајања и тип закључавања екрана. Апликација може и да предлаже корисницима да ажурирају закључавање екрана на одређени ниво, али корисници слободно могу да занемаре то и да иду на друге странице. Имајте на уму да се подаци за закључавање екрана не чувају као обичан текст, па апликација не зна тачну лозинку."</string>
+ <string name="permlab_postNotification" msgid="4875401198597803658">"приказивање обавештења"</string>
+ <string name="permdesc_postNotification" msgid="5974977162462877075">"Дозвољава апликацији да приказује обавештења"</string>
+ <string name="permlab_useBiometric" msgid="6314741124749633786">"користи биометријски хардвер"</string>
+ <string name="permdesc_useBiometric" msgid="7502858732677143410">"Дозвољава апликацији да користи биометријски хардвер за потврду идентитета"</string>
+ <string name="permlab_manageFingerprint" msgid="7432667156322821178">"управљај хардвером за отиске прстију"</string>
+ <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Дозвољава апликацији да активира методе за додавање и брисање шаблона отисака прстију који ће се користити."</string>
+ <string name="permlab_useFingerprint" msgid="1001421069766751922">"користи хардвер за отиске прстију"</string>
+ <string name="permdesc_useFingerprint" msgid="412463055059323742">"Дозвољава апликацији да користи хардвер за отиске прстију ради потврде идентитета"</string>
+ <string name="permlab_audioWrite" msgid="8501705294265669405">"измена музичке колекције"</string>
+ <string name="permdesc_audioWrite" msgid="8057399517013412431">"Дозвољава апликацији да мења музичку колекцију."</string>
+ <string name="permlab_videoWrite" msgid="5940738769586451318">"измена видео колекције"</string>
+ <string name="permdesc_videoWrite" msgid="6124731210613317051">"Дозвољава апликацији да мења видео колекцију."</string>
+ <string name="permlab_imagesWrite" msgid="1774555086984985578">"измена колекције слика"</string>
+ <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Дозвољава апликацији да мења колекцију слика."</string>
+ <string name="permlab_mediaLocation" msgid="7368098373378598066">"читање локација из медијске колекције"</string>
+ <string name="permdesc_mediaLocation" msgid="597912899423578138">"Дозвољава апликацији да чита локације из медијске колекције."</string>
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Користите биометрију"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користите биометрију или закључавање екрана"</string>
+ <string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдите свој идентитет"</string>
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Користите биометријски податак да бисте наставили"</string>
+ <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Користите биометријски податак или закључавање екрана да бисте наставили"</string>
+ <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометријски хардвер није доступан"</string>
+ <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Потврда идентитета је отказана"</string>
+ <string name="biometric_not_recognized" msgid="5106687642694635888">"Није препознато"</string>
+ <string name="biometric_error_canceled" msgid="8266582404844179778">"Потврда идентитета је отказана"</string>
+ <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Нисте подесили ни PIN, ни шаблон, ни лозинку"</string>
+ <string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при потврди идентитета"</string>
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користите закључавање екрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Употребите закључавање екрана да бисте наставили"</string>
+ <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Јако притисните сензор"</string>
+ <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Препознавање отиска прста није успело. Пробајте поново."</string>
+ <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Обришите сензор за отисак прста и пробајте поново"</string>
+ <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Обришите сензор и пробајте поново"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Јако притисните сензор"</string>
+ <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Превише споро сте померили прст. Пробајте поново."</string>
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте са другим отиском прста"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Превише је светло"</string>
+ <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Откривен је притисак дугмета за укључивање"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Пробајте да прилагодите"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Сваки пут помало промените положај прста"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
- <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisak prsta nije prepoznat"</string>
- <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Otisak prsta nije prepoznat"</string>
- <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string>
- <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je potvrđeno"</string>
- <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je potvrđeno. Pritisnite Potvrdi"</string>
- <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardver za otiske prstiju nije dostupan."</string>
- <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Podešavanje otiska prsta nije uspelo"</string>
- <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vreme za podešavanje otiska prsta je isteklo. Probajte ponovo."</string>
- <string name="fingerprint_error_canceled" msgid="540026881380070750">"Radnja sa otiskom prsta je otkazana."</string>
- <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Korisnik je otkazao radnju sa otiskom prsta."</string>
- <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string>
- <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string>
- <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Obrađivanje otiska prsta nije uspelo. Probajte ponovo."</string>
- <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registrovan nijedan otisak prsta."</string>
- <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
- <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
- <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ne možete da koristite senzor za otisak prsta. Posetite dobavljača za popravke"</string>
- <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Pritisnuto je dugme za uključivanje"</string>
- <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
- <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
- <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
- <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Koristite otisak prsta ili zaključavanje ekrana da biste nastavili"</string>
+ <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отисак прста није препознат"</string>
+ <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Отисак прста није препознат"</string>
+ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отисак прста је потврђен"</string>
+ <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лице је потврђено"</string>
+ <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лице је потврђено. Притисните Потврди"</string>
+ <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хардвер за отиске прстију није доступан."</string>
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Подешавање отиска прста није успело"</string>
+ <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Време за подешавање отиска прста је истекло. Пробајте поново."</string>
+ <string name="fingerprint_error_canceled" msgid="540026881380070750">"Радња са отиском прста је отказана."</string>
+ <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Корисник је отказао радњу са отиском прста."</string>
+ <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Превише покушаја. Користите закључавање екрана уместо тога."</string>
+ <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Превише покушаја. Користите закључавање екрана уместо тога."</string>
+ <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Обрађивање отиска прста није успело. Пробајте поново."</string>
+ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Није регистрован ниједан отисак прста."</string>
+ <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
+ <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
+ <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не можете да користите сензор за отисак прста. Посетите добављача за поправке"</string>
+ <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Притиснуто је дугме за укључивање"</string>
+ <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Наставите помоћу отиска прста"</string>
+ <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Користите отисак прста или закључавање екрана да бисте наставили"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Došlo je do problema. Probajte ponovo."</string>
- <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string>
- <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Otključavanje licem"</string>
- <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem sa otključavanje licem"</string>
- <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Dodirnite da biste izbrisali model lica, pa ponovo dodajte svoje lice"</string>
- <string name="face_setup_notification_title" msgid="8843461561970741790">"Podesite otključavanje licem"</string>
- <string name="face_setup_notification_content" msgid="5463999831057751676">"Otključajte telefon tako što ćete ga pogledati"</string>
- <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Da biste koristili otključavanje licem, uključite "<b>"pristup kameri"</b>" u odeljku Podešavanja > Privatnost"</string>
- <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Podesite još načina za otključavanje"</string>
- <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Dodirnite da biste dodali otisak prsta"</string>
- <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Otključavanje otiskom prsta"</string>
- <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Ne možete da koristite senzor za otisak prsta"</string>
- <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Posetite dobavljača za popravke."</string>
- <string name="face_acquired_insufficient" msgid="6889245852748492218">"Pravljenje modela lica nije uspelo. Probajte ponovo."</string>
- <string name="face_acquired_too_bright" msgid="8070756048978079164">"Previše je svetlo. Probajte sa slabijim osvetljenjem."</string>
- <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nema dovoljno svetla"</string>
- <string name="face_acquired_too_close" msgid="4453646176196302462">"Udaljite telefon"</string>
- <string name="face_acquired_too_far" msgid="2922278214231064859">"Približite telefon"</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"Pomerite telefon nagore"</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"Pomerite telefon nadole"</string>
- <string name="face_acquired_too_right" msgid="6245286514593540859">"Pomerite telefon ulevo"</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"Pomerite telefon udesno"</string>
- <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Gledajte pravo u uređaj."</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"Ne vidi se lice. Držite telefon u visini očiju."</string>
- <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Mnogo se pomerate. Držite telefon mirno."</string>
- <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Ponovo registrujte lice."</string>
- <string name="face_acquired_too_different" msgid="2520389515612972889">"Lice nije prepoznato. Probajte ponovo."</string>
- <string name="face_acquired_too_similar" msgid="8882920552674125694">"Malo pomerite glavu"</string>
- <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Gledajte pravo u telefon"</string>
- <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Gledajte pravo u telefon"</string>
- <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Gledajte pravo u telefon"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Uklonite sve što vam zaklanja lice."</string>
- <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Očistite gornji deo ekrana, uključujući crnu traku"</string>
+ <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Дошло је до проблема. Пробајте поново."</string>
+ <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона отиска прста"</string>
+ <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Откључавање лицем"</string>
+ <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Проблем са откључавање лицем"</string>
+ <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Додирните да бисте избрисали модел лица, па поново додајте своје лице"</string>
+ <string name="face_setup_notification_title" msgid="8843461561970741790">"Подесите откључавање лицем"</string>
+ <string name="face_setup_notification_content" msgid="5463999831057751676">"Откључајте телефон тако што ћете га погледати"</string>
+ <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Да бисте користили откључавање лицем, укључите "<b>"приступ камери"</b>" у одељку Подешавања > Приватност"</string>
+ <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Подесите још начина за откључавање"</string>
+ <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Додирните да бисте додали отисак прста"</string>
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Откључавање отиском прста"</string>
+ <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Не можете да користите сензор за отисак прста"</string>
+ <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Посетите добављача за поправке."</string>
+ <string name="face_acquired_insufficient" msgid="6889245852748492218">"Прављење модела лица није успело. Пробајте поново."</string>
+ <string name="face_acquired_too_bright" msgid="8070756048978079164">"Превише је светло. Пробајте са слабијим осветљењем."</string>
+ <string name="face_acquired_too_dark" msgid="8539853432479385326">"Нема довољно светла"</string>
+ <string name="face_acquired_too_close" msgid="4453646176196302462">"Удаљите телефон"</string>
+ <string name="face_acquired_too_far" msgid="2922278214231064859">"Приближите телефон"</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"Померите телефон нагоре"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"Померите телефон надоле"</string>
+ <string name="face_acquired_too_right" msgid="6245286514593540859">"Померите телефон улево"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"Померите телефон удесно"</string>
+ <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Гледајте право у уређај."</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"Не види се лице. Држите телефон у висини очију."</string>
+ <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Много се померате. Држите телефон мирно."</string>
+ <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Поново региструјте лице."</string>
+ <string name="face_acquired_too_different" msgid="2520389515612972889">"Лице није препознато. Пробајте поново."</string>
+ <string name="face_acquired_too_similar" msgid="8882920552674125694">"Мало померите главу"</string>
+ <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Гледајте право у телефон"</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Гледајте право у телефон"</string>
+ <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Гледајте право у телефон"</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Уклоните све што вам заклања лице."</string>
+ <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Очистите горњи део екрана, укључујући црну траку"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
<!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
<skip />
- <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Pravljenje modela lica nije uspelo. Probajte ponovo."</string>
- <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Otkrivene su tamne naočari. Lice mora da bude potpuno vidljivo."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Otkriveno je prekrivanje lica. Lice mora da bude potpuno vidljivo."</string>
+ <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Прављење модела лица није успело. Пробајте поново."</string>
+ <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Откривене су тамне наочари. Лице мора да буде потпуно видљиво."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Откривено је прекривање лица. Лице мора да буде потпуно видљиво."</string>
<string-array name="face_acquired_vendor">
</string-array>
- <string name="face_error_hw_not_available" msgid="5085202213036026288">"Provera lica nije uspela. Hardver nije dostupan."</string>
- <string name="face_error_timeout" msgid="2598544068593889762">"Probajte ponovo otključavanje licem"</string>
- <string name="face_error_no_space" msgid="5649264057026021723">"Novi podaci o licu nisu sačuvani. Prvo izbrišete prethodne."</string>
- <string name="face_error_canceled" msgid="2164434737103802131">"Obrada lica je otkazana."</string>
- <string name="face_error_user_canceled" msgid="5766472033202928373">"Korisnik je otkazao otključavanje licem"</string>
- <string name="face_error_lockout" msgid="7864408714994529437">"Previše pokušaja. Probajte ponovo kasnije."</string>
- <string name="face_error_lockout_permanent" msgid="3277134834042995260">"Previše pokušaja. Otključavanje licem je onemogućeno."</string>
- <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Previše pokušaja. Koristite zaključavanje ekrana za to."</string>
- <string name="face_error_unable_to_process" msgid="5723292697366130070">"Provera lica nije uspela. Probajte ponovo."</string>
- <string name="face_error_not_enrolled" msgid="1134739108536328412">"Niste podesili otključavanje licem"</string>
- <string name="face_error_hw_not_present" msgid="7940978724978763011">"Otključavanje licem nije podržano na ovom uređaju"</string>
- <string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je privremeno onemogućen."</string>
- <string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
- <string name="face_app_setting_name" msgid="5854024256907828015">"Koristite otključavanje licem"</string>
- <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristite zaključavanje licem ili zaključavanje ekrana"</string>
- <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Potvrdite identitet licem da biste nastavili"</string>
- <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Koristite lice ili zaključavanje ekrana da biste nastavili"</string>
+ <string name="face_error_hw_not_available" msgid="5085202213036026288">"Провера лица није успела. Хардвер није доступан."</string>
+ <string name="face_error_timeout" msgid="2598544068593889762">"Пробајте поново откључавање лицем"</string>
+ <string name="face_error_no_space" msgid="5649264057026021723">"Нови подаци о лицу нису сачувани. Прво избришете претходне."</string>
+ <string name="face_error_canceled" msgid="2164434737103802131">"Обрада лица је отказана."</string>
+ <string name="face_error_user_canceled" msgid="5766472033202928373">"Корисник је отказао откључавање лицем"</string>
+ <string name="face_error_lockout" msgid="7864408714994529437">"Превише покушаја. Пробајте поново касније."</string>
+ <string name="face_error_lockout_permanent" msgid="3277134834042995260">"Превише покушаја. Откључавање лицем је онемогућено."</string>
+ <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Превише покушаја. Користите закључавање екрана за то."</string>
+ <string name="face_error_unable_to_process" msgid="5723292697366130070">"Провера лица није успела. Пробајте поново."</string>
+ <string name="face_error_not_enrolled" msgid="1134739108536328412">"Нисте подесили откључавање лицем"</string>
+ <string name="face_error_hw_not_present" msgid="7940978724978763011">"Откључавање лицем није подржано на овом уређају"</string>
+ <string name="face_error_security_update_required" msgid="5076017208528750161">"Сензор је привремено онемогућен."</string>
+ <string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
+ <string name="face_app_setting_name" msgid="5854024256907828015">"Користите откључавање лицем"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Користите закључавање лицем или закључавање екрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Потврдите идентитет лицем да бисте наставили"</string>
+ <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Користите лице или закључавање екрана да бисте наставили"</string>
<string-array name="face_error_vendor">
</string-array>
- <string name="face_error_vendor_unknown" msgid="7387005932083302070">"Došlo je do problema. Probajte ponovo."</string>
- <string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
- <string name="permlab_readSyncSettings" msgid="6250532864893156277">"čitanje podešavanja sinhronizacije"</string>
- <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Dozvoljava aplikaciji da čita podešavanja sinhronizacije za nalog. Na primer, ovako može da se utvrdi da li je aplikacija Ljudi sinhronizovana sa nalogom."</string>
- <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"uključivanje i isključivanje sinhronizacije"</string>
- <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Dozvoljava aplikaciji da menja podešavanja sinhronizacije za nalog. Na primer, ovako može da se omogući sinhronizacija aplikacije Ljudi sa nalogom."</string>
- <string name="permlab_readSyncStats" msgid="3747407238320105332">"čitanje statistike o sinhronizaciji"</string>
- <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Dozvoljava aplikaciji da čita statistiku sinhronizacije za nalog, uključujući istoriju sinhronizovanih događaja i količinu podataka koji se sinhronizuju."</string>
- <string name="permlab_sdcardRead" msgid="5791467020950064920">"čitanje sadržaja deljenog memorijskog prostora"</string>
- <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Dozvoljava aplikaciji da čita sadržaj deljenog memorijskog prostora."</string>
- <string name="permlab_readMediaAudio" msgid="8723513075731763810">"čitanje audio fajlova iz deljenog memorijskog prostora"</string>
- <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Omogućava aplikaciji da čita audio fajlove iz deljenog memorijskog prostora."</string>
- <string name="permlab_readMediaVideo" msgid="7768003311260655007">"čitanje video fajlova iz deljenog memorijskog prostora"</string>
- <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Omogućava aplikaciji da čita video fajlove iz deljenog memorijskog prostora."</string>
- <string name="permlab_readMediaImages" msgid="4057590631020986789">"čitanje fajlova slika iz deljenog memorijskog prostora"</string>
- <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Omogućava aplikaciji da čita fajlove slika iz deljenog memorijskog prostora."</string>
- <string name="permlab_sdcardWrite" msgid="4863021819671416668">"menjanje ili brisanje sadržaja deljenog memorijskog prostora"</string>
- <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Dozvoljava aplikaciji da upisuje sadržaj deljenog memorijskog prostora."</string>
- <string name="permlab_use_sip" msgid="8250774565189337477">"upućivanje/prijem SIP poziva"</string>
- <string name="permdesc_use_sip" msgid="3590270893253204451">"Omogućava aplikaciji da upućuje i prima SIP pozive."</string>
- <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"registruje nove veze sa telekomunikacionim mrežama preko SIM kartice"</string>
- <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Dozvoljava aplikaciji da registruje nove veze sa telekomunikacionim mrežama preko SIM kartice."</string>
- <string name="permlab_register_call_provider" msgid="6135073566140050702">"registruje nove veze sa telekomunikacionim mrežama"</string>
- <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Dozvoljava aplikaciji da registruje nove veze sa telekomunikacionim mrežama."</string>
- <string name="permlab_connection_manager" msgid="3179365584691166915">"upravljanje vezama sa telekomunikacionim mrežama"</string>
- <string name="permdesc_connection_manager" msgid="1426093604238937733">"Dozvoljava aplikaciji da upravlja vezama sa telekomunikacionim mrežama."</string>
- <string name="permlab_bind_incall_service" msgid="5990625112603493016">"komuniciraj sa ekranom tokom poziva"</string>
- <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Dozvoljava aplikaciji da kontroliše kada i kako se korisniku prikazuje ekran tokom poziva."</string>
- <string name="permlab_bind_connection_service" msgid="5409268245525024736">"da stupa u interakciju sa telefonskim uslugama"</string>
- <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Dozvoljava interakciju aplikacije sa telefonskim uslugama radi upućivanja/primanja poziva."</string>
- <string name="permlab_control_incall_experience" msgid="6436863486094352987">"pružaj korisnički doživljaj tokom poziva"</string>
- <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Dozvoljava aplikaciji da pruža korisnički doživljaj tokom poziva."</string>
- <string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"čita istoriju korišćenja mreže"</string>
- <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Dozvoljava aplikaciji da čita istoriju korišćenja mreže za posebne mreže i aplikacije."</string>
- <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"upravljanje smernicama za mrežu"</string>
- <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Dozvoljava aplikaciji da upravlja smernicama za mrežu i određuje posebna pravila za aplikaciju."</string>
- <string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"izmenite obračunavanje korišćenja mreže"</string>
- <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Dozvoljava aplikaciji da izmeni način na koji aplikacije koriste mrežu. Ne koriste je uobičajene aplikacije."</string>
- <string name="permlab_accessNotifications" msgid="7130360248191984741">"pristup obaveštenjima"</string>
- <string name="permdesc_accessNotifications" msgid="761730149268789668">"Dozvoljava aplikaciji da preuzima, ispituje i briše obaveštenja, uključujući ona koja postavljaju druge aplikacije."</string>
- <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"povezivanje sa uslugom monitora obaveštenja"</string>
- <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"Dozvoljava vlasniku da se poveže sa interfejsom usluge monitora obaveštenja najvišeg nivoa. Uobičajene aplikacije nikada ne bi trebalo da je koriste."</string>
- <string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"poveži sa uslugom dobavljača uslova"</string>
- <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Dozvoljava vlasniku da se poveže sa interfejsom najvišeg nivoa usluge dobavljača uslova. Ne bi trebalo nikada da bude potrebno za uobičajene aplikacije."</string>
- <string name="permlab_bindDreamService" msgid="4776175992848982706">"povezivanje sa uslugom sanjarenja"</string>
- <string name="permdesc_bindDreamService" msgid="9129615743300572973">"Dozvoljava vlasniku da se poveže sa interfejsom usluge sanjarenja najvišeg nivoa. Uobičajene aplikacije nikada ne bi trebalo da je koriste."</string>
- <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"pozivanje aplikacije sa konfiguracijom koju određuje operater"</string>
- <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Dozvoljava vlasniku da poziva aplikaciju sa konfiguracijom koju određuje operater. Uobičajene aplikacije nikada ne bi trebalo da je koriste."</string>
- <string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"praćenje podataka o uslovima na mreži"</string>
- <string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Dozvoljava aplikaciji da prati podatke o uslovima na mreži. Ne bi nikada trebalo da bude potrebno za normalne aplikacije."</string>
- <string name="permlab_setInputCalibration" msgid="932069700285223434">"promeni kalibraciju ulaznog uređaja"</string>
- <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Dozvoljava aplikaciji da modifikuje parametre kalibracije dodirnog ekrana. Ne bi trebalo da bude potrebno za normalne aplikacije."</string>
- <string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"pristup DRM sertifikatima"</string>
- <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Dozvoljava aplikaciji da dodeljuje i koristi DRM sertifikate. Nikada ne bi trebalo da se koristi za uobičajene aplikacije."</string>
- <string name="permlab_handoverStatus" msgid="7620438488137057281">"prijem statusa prebacivanja pomoću Android prebacivanja"</string>
- <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Dozvoljava ovoj aplikaciji da prima informacije o aktuelnim prebacivanjima pomoću Android prebacivanja"</string>
- <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"uklanjaj DRM sertifikate"</string>
- <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Dozvoljava aplikaciji da uklanja DRM sertifikate. Nikada ne bi trebalo da se koristi za obične aplikacije."</string>
- <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"povezivanje sa uslugom za razmenu poruka mobilnog operatera"</string>
- <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Dozvoljava vlasniku da se poveže sa interfejsom najvišeg nivoa za uslugu za razmenu poruka mobilnog operatera. Nikada ne bi trebalo da bude potrebno za standardne aplikacije."</string>
- <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"povezivanje sa uslugama operatera"</string>
- <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Dozvoljava vlasniku da se poveže sa uslugama operatera. Nikada ne bi trebalo da bude potrebno za obične aplikacije."</string>
- <string name="permlab_access_notification_policy" msgid="5524112842876975537">"pristupaj podešavanju Ne uznemiravaj"</string>
- <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Dozvoljava aplikaciji da čita i upisuje konfiguraciju podešavanja Ne uznemiravaj."</string>
- <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"početak korišćenja dozvole za pregled"</string>
- <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Dozvoljava vlasniku da započne korišćenje dozvole za aplikaciju. Nikada ne bi trebalo da bude potrebna za uobičajene aplikacije."</string>
- <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"pokretanje pregleda odluka o dozvolama"</string>
- <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Dozvoljava vlasniku da pokrene ekran za proveru odluka o dozvolama. Nikada ne bi trebalo da bude potrebno za obične aplikacije."</string>
- <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"pokretanje prikaza funkcija aplikacije"</string>
- <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Dozvoljava nosiocu dozvole da započne pregledanje informacija o funkcijama aplikacije."</string>
- <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"pristup podacima senzora pri velikoj brzini uzorkovanja"</string>
- <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Dozvoljava aplikaciji da uzima uzorak podataka senzora pri brzini većoj od 200 Hz"</string>
- <string name="policylab_limitPassword" msgid="4851829918814422199">"Podešavanje pravila za lozinku"</string>
- <string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za zaključavanje ekrana."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"Nadgledajte pokušaje otključavanja ekrana"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Prati broj netačno unetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše podatke sa tableta ako je netačna lozinka uneta previše puta."</string>
- <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava Android TV uređaj ili briše sve podatke sa Android TV uređaja ako se unese previše netačnih lozinki."</string>
- <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava sistem za info-zabavu ili briše sve podatke sa sistema za info-zabavu ako je netačna lozinka uneta previše puta."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava telefon ili briše sve podatke sa telefona ako je netačna lozinka uneta previše puta."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava tablet ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava Android TV uređaj ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava sistem za info-zabavu ili briše sve podatke ovog profila ako se unese previše netačnih lozinki."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava telefon ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
- <string name="policylab_resetPassword" msgid="214556238645096520">"Promena zaključavanja ekrana"</string>
- <string name="policydesc_resetPassword" msgid="4626419138439341851">"Menja zaključavanje ekrana."</string>
- <string name="policylab_forceLock" msgid="7360335502968476434">"Zaključavanje ekrana"</string>
- <string name="policydesc_forceLock" msgid="1008844760853899693">"Kontrola načina i vremena zaključavanja ekrana."</string>
- <string name="policylab_wipeData" msgid="1359485247727537311">"Brisanje svih podataka"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Brisanje podataka na tabletu bez upozorenja resetovanjem na fabrička podešavanja."</string>
- <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Briše podatke Android TV uređaja bez upozorenja pomoću resetovanja na fabrička podešavanja."</string>
- <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Briše podatke na sistemu za info-zabavu bez upozorenja resetovanjem na fabrička podešavanja."</string>
- <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Brisanje podataka na telefonu bez upozorenja resetovanjem na fabrička podešavanja."</string>
- <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Brisanje podataka profila"</string>
- <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Obriši podatke korisnika"</string>
- <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Briše podatke ovog korisnika na ovom tabletu bez upozorenja."</string>
- <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Briše podatke ovog korisnika na ovom Android TV uređaju bez upozorenja."</string>
- <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Briše podatke ovog profila na ovom sistemu za info-zabavu bez upozorenja."</string>
- <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Briše podatke ovog korisnika na ovom telefonu bez upozorenja."</string>
- <string name="policylab_setGlobalProxy" msgid="215332221188670221">"Podesite globalni proksi server uređaja"</string>
- <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Podešava globalni proksi uređaja koji će se koristiti dok su smernice omogućene. Samo vlasnik uređaja može da podesi globalni proksi."</string>
- <string name="policylab_expirePassword" msgid="6015404400532459169">"Podesi istek. lozin. za zaklj. ekr."</string>
- <string name="policydesc_expirePassword" msgid="9136524319325960675">"Menja koliko često lozinka, PIN ili šablon za zaključavanje ekrana mora da se menja."</string>
- <string name="policylab_encryptedStorage" msgid="9012936958126670110">"Podešavanje šifrovanja skladišta"</string>
- <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Zahteva da sačuvani podaci aplikacije budu šifrovani."</string>
- <string name="policylab_disableCamera" msgid="5749486347810162018">"Onemogućavanje kamera"</string>
- <string name="policydesc_disableCamera" msgid="3204405908799676104">"Sprečite korišćenje svih kamera uređaja."</string>
- <string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"Onemogućavanje funkcija zaklj. ekrana"</string>
- <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"Sprečava korišćenje nekih funkcija zaključavanja ekrana."</string>
+ <string name="face_error_vendor_unknown" msgid="7387005932083302070">"Дошло је до проблема. Пробајте поново."</string>
+ <string name="face_icon_content_description" msgid="465030547475916280">"Икона лица"</string>
+ <string name="permlab_readSyncSettings" msgid="6250532864893156277">"читање подешавања синхронизације"</string>
+ <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Дозвољава апликацији да чита подешавања синхронизације за налог. На пример, овако може да се утврди да ли је апликација Људи синхронизована са налогом."</string>
+ <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"укључивање и искључивање синхронизације"</string>
+ <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Дозвољава апликацији да мења подешавања синхронизације за налог. На пример, овако може да се омогући синхронизација апликације Људи са налогом."</string>
+ <string name="permlab_readSyncStats" msgid="3747407238320105332">"читање статистике о синхронизацији"</string>
+ <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Дозвољава апликацији да чита статистику синхронизације за налог, укључујући историју синхронизованих догађаја и количину података који се синхронизују."</string>
+ <string name="permlab_sdcardRead" msgid="5791467020950064920">"читање садржаја дељеног меморијског простора"</string>
+ <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Дозвољава апликацији да чита садржај дељеног меморијског простора."</string>
+ <string name="permlab_readMediaAudio" msgid="8723513075731763810">"читање аудио фајлова из дељеног меморијског простора"</string>
+ <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Омогућава апликацији да чита аудио фајлове из дељеног меморијског простора."</string>
+ <string name="permlab_readMediaVideo" msgid="7768003311260655007">"читање видео фајлова из дељеног меморијског простора"</string>
+ <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Омогућава апликацији да чита видео фајлове из дељеног меморијског простора."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"читање фајлова слика из дељеног меморијског простора"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Омогућава апликацији да чита фајлове слика из дељеног меморијског простора."</string>
+ <string name="permlab_sdcardWrite" msgid="4863021819671416668">"мењање или брисање садржаја дељеног меморијског простора"</string>
+ <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Дозвољава апликацији да уписује садржај дељеног меморијског простора."</string>
+ <string name="permlab_use_sip" msgid="8250774565189337477">"упућивање/пријем SIP позива"</string>
+ <string name="permdesc_use_sip" msgid="3590270893253204451">"Омогућава апликацији да упућује и прима SIP позиве."</string>
+ <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"региструје нове везе са телекомуникационим мрежама преко SIM картице"</string>
+ <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Дозвољава апликацији да региструје нове везе са телекомуникационим мрежама преко SIM картице."</string>
+ <string name="permlab_register_call_provider" msgid="6135073566140050702">"региструје нове везе са телекомуникационим мрежама"</string>
+ <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Дозвољава апликацији да региструје нове везе са телекомуникационим мрежама."</string>
+ <string name="permlab_connection_manager" msgid="3179365584691166915">"управљање везама са телекомуникационим мрежама"</string>
+ <string name="permdesc_connection_manager" msgid="1426093604238937733">"Дозвољава апликацији да управља везама са телекомуникационим мрежама."</string>
+ <string name="permlab_bind_incall_service" msgid="5990625112603493016">"комуницирај са екраном током позива"</string>
+ <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Дозвољава апликацији да контролише када и како се кориснику приказује екран током позива."</string>
+ <string name="permlab_bind_connection_service" msgid="5409268245525024736">"да ступа у интеракцију са телефонским услугама"</string>
+ <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Дозвољава интеракцију апликације са телефонским услугама ради упућивања/примања позива."</string>
+ <string name="permlab_control_incall_experience" msgid="6436863486094352987">"пружај кориснички доживљај током позива"</string>
+ <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Дозвољава апликацији да пружа кориснички доживљај током позива."</string>
+ <string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"чита историју коришћења мреже"</string>
+ <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Дозвољава апликацији да чита историју коришћења мреже за посебне мреже и апликације."</string>
+ <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"управљање смерницама за мрежу"</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Дозвољава апликацији да управља смерницама за мрежу и одређује посебна правила за апликацију."</string>
+ <string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"измените обрачунавање коришћења мреже"</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Дозвољава апликацији да измени начин на који апликације користе мрежу. Не користе је уобичајене апликације."</string>
+ <string name="permlab_accessNotifications" msgid="7130360248191984741">"приступ обавештењима"</string>
+ <string name="permdesc_accessNotifications" msgid="761730149268789668">"Дозвољава апликацији да преузима, испитује и брише обавештења, укључујући она која постављају друге апликације."</string>
+ <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"повезивање са услугом монитора обавештења"</string>
+ <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"Дозвољава власнику да се повеже са интерфејсом услуге монитора обавештења највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
+ <string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"повежи са услугом добављача услова"</string>
+ <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа услуге добављача услова. Не би требало никада да буде потребно за уобичајене апликације."</string>
+ <string name="permlab_bindDreamService" msgid="4776175992848982706">"повезивање са услугом сањарења"</string>
+ <string name="permdesc_bindDreamService" msgid="9129615743300572973">"Дозвољава власнику да се повеже са интерфејсом услуге сањарења највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
+ <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"позивање апликације са конфигурацијом коју одређује оператер"</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Дозвољава власнику да позива апликацију са конфигурацијом коју одређује оператер. Уобичајене апликације никада не би требало да је користе."</string>
+ <string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"праћење података о условима на мрежи"</string>
+ <string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Дозвољава апликацији да прати податке о условима на мрежи. Не би никада требало да буде потребно за нормалне апликације."</string>
+ <string name="permlab_setInputCalibration" msgid="932069700285223434">"промени калибрацију улазног уређаја"</string>
+ <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Дозвољава апликацији да модификује параметре калибрације додирног екрана. Не би требало да буде потребно за нормалне апликације."</string>
+ <string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"приступ DRM сертификатима"</string>
+ <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Дозвољава апликацији да додељује и користи DRM сертификате. Никада не би требало да се користи за уобичајене апликације."</string>
+ <string name="permlab_handoverStatus" msgid="7620438488137057281">"пријем статуса пребацивања помоћу Android пребацивања"</string>
+ <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Дозвољава овој апликацији да прима информације о актуелним пребацивањима помоћу Android пребацивања"</string>
+ <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"уклањај DRM сертификате"</string>
+ <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Дозвољава апликацији да уклања DRM сертификате. Никада не би требало да се користи за обичне апликације."</string>
+ <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"повезивање са услугом за размену порука мобилног оператера"</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа за услугу за размену порука мобилног оператера. Никада не би требало да буде потребно за стандардне апликације."</string>
+ <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"повезивање са услугама оператера"</string>
+ <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Дозвољава власнику да се повеже са услугама оператера. Никада не би требало да буде потребно за обичне апликације."</string>
+ <string name="permlab_access_notification_policy" msgid="5524112842876975537">"приступај подешавању Не узнемиравај"</string>
+ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Дозвољава апликацији да чита и уписује конфигурацију подешавања Не узнемиравај."</string>
+ <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"почетак коришћења дозволе за преглед"</string>
+ <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Дозвољава власнику да започне коришћење дозволе за апликацију. Никада не би требало да буде потребна за уобичајене апликације."</string>
+ <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"покретање прегледа одлука о дозволама"</string>
+ <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Дозвољава власнику да покрене екран за проверу одлука о дозволама. Никада не би требало да буде потребно за обичне апликације."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"покретање приказа функција апликације"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Дозвољава носиоцу дозволе да започне прегледање информација о функцијама апликације."</string>
+ <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"приступ подацима сензора при великој брзини узорковања"</string>
+ <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Дозвољава апликацији да узима узорак података сензора при брзини већој од 200 Hz"</string>
+ <string name="policylab_limitPassword" msgid="4851829918814422199">"Подешавање правила за лозинку"</string>
+ <string name="policydesc_limitPassword" msgid="4105491021115793793">"Контролише дужину и знакове дозвољене у лозинкама и PIN-овима за закључавање екрана."</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"Надгледајте покушаје откључавања екрана"</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Прати број нетачно унетих лозинки приликом откључавања екрана и закључава таблет или брише податке са таблета ако је нетачна лозинка унета превише пута."</string>
+ <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава Android TV уређај или брише све податке са Android TV уређаја ако се унесе превише нетачних лозинки."</string>
+ <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Прати број нетачно унетих лозинки при откључавању екрана и закључава систем за инфо-забаву или брише све податке са система за инфо-забаву ако је нетачна лозинка унета превише пута."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Прати број нетачно унетих лозинки при откључавању екрана и закључава телефон или брише све податке са телефона ако је нетачна лозинка унета превише пута."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава таблет или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава Android TV уређај или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава систем за инфо-забаву или брише све податке овог профила ако се унесе превише нетачних лозинки."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава телефон или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
+ <string name="policylab_resetPassword" msgid="214556238645096520">"Промена закључавања екрана"</string>
+ <string name="policydesc_resetPassword" msgid="4626419138439341851">"Мења закључавање екрана."</string>
+ <string name="policylab_forceLock" msgid="7360335502968476434">"Закључавање екрана"</string>
+ <string name="policydesc_forceLock" msgid="1008844760853899693">"Контрола начина и времена закључавања екрана."</string>
+ <string name="policylab_wipeData" msgid="1359485247727537311">"Брисање свих података"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Брисање података на таблету без упозорења ресетовањем на фабричка подешавања."</string>
+ <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Брише податке Android TV уређаја без упозорења помоћу ресетовања на фабричка подешавања."</string>
+ <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Брише податке на систему за инфо-забаву без упозорења ресетовањем на фабричка подешавања."</string>
+ <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Брисање података на телефону без упозорења ресетовањем на фабричка подешавања."</string>
+ <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Брисање података профила"</string>
+ <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Обриши податке корисника"</string>
+ <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Брише податке овог корисника на овом таблету без упозорења."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Брише податке овог корисника на овом Android TV уређају без упозорења."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Брише податке овог профила на овом систему за инфо-забаву без упозорења."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Брише податке овог корисника на овом телефону без упозорења."</string>
+ <string name="policylab_setGlobalProxy" msgid="215332221188670221">"Подесите глобални прокси сервер уређаја"</string>
+ <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Подешава глобални прокси уређаја који ће се користити док су смернице омогућене. Само власник уређаја може да подеси глобални прокси."</string>
+ <string name="policylab_expirePassword" msgid="6015404400532459169">"Подеси истек. лозин. за закљ. екр."</string>
+ <string name="policydesc_expirePassword" msgid="9136524319325960675">"Мења колико често лозинка, PIN или шаблон за закључавање екрана мора да се мења."</string>
+ <string name="policylab_encryptedStorage" msgid="9012936958126670110">"Подешавање шифровања складишта"</string>
+ <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Захтева да сачувани подаци апликације буду шифровани."</string>
+ <string name="policylab_disableCamera" msgid="5749486347810162018">"Онемогућавање камера"</string>
+ <string name="policydesc_disableCamera" msgid="3204405908799676104">"Спречите коришћење свих камера уређаја."</string>
+ <string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"Онемогућавање функција закљ. екрана"</string>
+ <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"Спречава коришћење неких функција закључавања екрана."</string>
<string-array name="phoneTypes">
- <item msgid="8996339953292723951">"Kuća"</item>
- <item msgid="7740243458912727194">"Mobilni"</item>
- <item msgid="8526146065496663766">"Posao"</item>
- <item msgid="8150904584178569699">"Faks na poslu"</item>
- <item msgid="4537253139152229577">"Faks kod kuće"</item>
- <item msgid="6751245029698664340">"Pejdžer"</item>
- <item msgid="1692790665884224905">"Drugo"</item>
- <item msgid="6216981255272016212">"Prilagođeno"</item>
+ <item msgid="8996339953292723951">"Кућа"</item>
+ <item msgid="7740243458912727194">"Мобилни"</item>
+ <item msgid="8526146065496663766">"Посао"</item>
+ <item msgid="8150904584178569699">"Факс на послу"</item>
+ <item msgid="4537253139152229577">"Факс код куће"</item>
+ <item msgid="6751245029698664340">"Пејџер"</item>
+ <item msgid="1692790665884224905">"Друго"</item>
+ <item msgid="6216981255272016212">"Прилагођено"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item msgid="7786349763648997741">"Kuća"</item>
- <item msgid="435564470865989199">"Posao"</item>
- <item msgid="4199433197875490373">"Drugo"</item>
- <item msgid="3233938986670468328">"Prilagođeno"</item>
+ <item msgid="7786349763648997741">"Кућа"</item>
+ <item msgid="435564470865989199">"Посао"</item>
+ <item msgid="4199433197875490373">"Друго"</item>
+ <item msgid="3233938986670468328">"Прилагођено"</item>
</string-array>
<string-array name="postalAddressTypes">
- <item msgid="3861463339764243038">"Kuća"</item>
- <item msgid="5472578890164979109">"Posao"</item>
- <item msgid="5718921296646594739">"Drugo"</item>
- <item msgid="5523122236731783179">"Prilagođeno"</item>
+ <item msgid="3861463339764243038">"Кућа"</item>
+ <item msgid="5472578890164979109">"Посао"</item>
+ <item msgid="5718921296646594739">"Друго"</item>
+ <item msgid="5523122236731783179">"Прилагођено"</item>
</string-array>
<string-array name="imAddressTypes">
- <item msgid="588088543406993772">"Kuća"</item>
- <item msgid="5503060422020476757">"Posao"</item>
- <item msgid="2530391194653760297">"Drugo"</item>
- <item msgid="7640927178025203330">"Prilagođeno"</item>
+ <item msgid="588088543406993772">"Кућа"</item>
+ <item msgid="5503060422020476757">"Посао"</item>
+ <item msgid="2530391194653760297">"Друго"</item>
+ <item msgid="7640927178025203330">"Прилагођено"</item>
</string-array>
<string-array name="organizationTypes">
- <item msgid="6144047813304847762">"Posao"</item>
- <item msgid="7402720230065674193">"Drugo"</item>
- <item msgid="808230403067569648">"Prilagođeno"</item>
+ <item msgid="6144047813304847762">"Посао"</item>
+ <item msgid="7402720230065674193">"Друго"</item>
+ <item msgid="808230403067569648">"Прилагођено"</item>
</string-array>
<string-array name="imProtocols">
<item msgid="7535761744432206400">"AIM"</item>
@@ -837,45 +837,45 @@
<item msgid="4717545739447438044">"ICQ"</item>
<item msgid="8293711853624033835">"Jabber"</item>
</string-array>
- <string name="phoneTypeCustom" msgid="5120365721260686814">"Prilagođeno"</string>
- <string name="phoneTypeHome" msgid="3880132427643623588">"Kuća"</string>
- <string name="phoneTypeMobile" msgid="1178852541462086735">"Mobilni"</string>
- <string name="phoneTypeWork" msgid="6604967163358864607">"Posao"</string>
- <string name="phoneTypeFaxWork" msgid="6757519896109439123">"Faks na poslu"</string>
- <string name="phoneTypeFaxHome" msgid="6678559953115904345">"Faks kod kuće"</string>
- <string name="phoneTypePager" msgid="576402072263522767">"Pejdžer"</string>
- <string name="phoneTypeOther" msgid="6918196243648754715">"Drugo"</string>
- <string name="phoneTypeCallback" msgid="3455781500844157767">"Povratni poziv"</string>
- <string name="phoneTypeCar" msgid="4604775148963129195">"Automobil"</string>
- <string name="phoneTypeCompanyMain" msgid="4482773154536455441">"Poslovni glavni"</string>
+ <string name="phoneTypeCustom" msgid="5120365721260686814">"Прилагођено"</string>
+ <string name="phoneTypeHome" msgid="3880132427643623588">"Кућа"</string>
+ <string name="phoneTypeMobile" msgid="1178852541462086735">"Мобилни"</string>
+ <string name="phoneTypeWork" msgid="6604967163358864607">"Посао"</string>
+ <string name="phoneTypeFaxWork" msgid="6757519896109439123">"Факс на послу"</string>
+ <string name="phoneTypeFaxHome" msgid="6678559953115904345">"Факс код куће"</string>
+ <string name="phoneTypePager" msgid="576402072263522767">"Пејџер"</string>
+ <string name="phoneTypeOther" msgid="6918196243648754715">"Друго"</string>
+ <string name="phoneTypeCallback" msgid="3455781500844157767">"Повратни позив"</string>
+ <string name="phoneTypeCar" msgid="4604775148963129195">"Аутомобил"</string>
+ <string name="phoneTypeCompanyMain" msgid="4482773154536455441">"Пословни главни"</string>
<string name="phoneTypeIsdn" msgid="2496238954533998512">"ISDN"</string>
- <string name="phoneTypeMain" msgid="5199722006991000111">"Glavni"</string>
- <string name="phoneTypeOtherFax" msgid="3037145630364770357">"Drugi faks"</string>
- <string name="phoneTypeRadio" msgid="2637819130239264771">"Radio"</string>
- <string name="phoneTypeTelex" msgid="2558783611711876562">"Teleks"</string>
+ <string name="phoneTypeMain" msgid="5199722006991000111">"Главни"</string>
+ <string name="phoneTypeOtherFax" msgid="3037145630364770357">"Други факс"</string>
+ <string name="phoneTypeRadio" msgid="2637819130239264771">"Радио"</string>
+ <string name="phoneTypeTelex" msgid="2558783611711876562">"Телекс"</string>
<string name="phoneTypeTtyTdd" msgid="532038552105328779">"TTY TDD"</string>
- <string name="phoneTypeWorkMobile" msgid="7522314392003565121">"Poslovni mobilni"</string>
- <string name="phoneTypeWorkPager" msgid="3748332310638505234">"Poslovni pejdžer"</string>
- <string name="phoneTypeAssistant" msgid="757550783842231039">"Pomoćnik"</string>
+ <string name="phoneTypeWorkMobile" msgid="7522314392003565121">"Пословни мобилни"</string>
+ <string name="phoneTypeWorkPager" msgid="3748332310638505234">"Пословни пејџер"</string>
+ <string name="phoneTypeAssistant" msgid="757550783842231039">"Помоћник"</string>
<string name="phoneTypeMms" msgid="1799747455131365989">"MMS"</string>
- <string name="eventTypeCustom" msgid="3257367158986466481">"Prilagođeno"</string>
- <string name="eventTypeBirthday" msgid="7770026752793912283">"Rođendan"</string>
- <string name="eventTypeAnniversary" msgid="4684702412407916888">"Godišnjica"</string>
- <string name="eventTypeOther" msgid="530671238533887997">"Drugi"</string>
- <string name="emailTypeCustom" msgid="1809435350482181786">"Prilagođeno"</string>
- <string name="emailTypeHome" msgid="1597116303154775999">"Kuća"</string>
- <string name="emailTypeWork" msgid="2020095414401882111">"Posao"</string>
- <string name="emailTypeOther" msgid="5131130857030897465">"Drugo"</string>
- <string name="emailTypeMobile" msgid="787155077375364230">"Mobilni"</string>
- <string name="postalTypeCustom" msgid="5645590470242939129">"Prilagođeno"</string>
- <string name="postalTypeHome" msgid="7562272480949727912">"Kuća"</string>
- <string name="postalTypeWork" msgid="8553425424652012826">"Posao"</string>
- <string name="postalTypeOther" msgid="7094245413678857420">"Drugo"</string>
- <string name="imTypeCustom" msgid="5653384545085765570">"Prilagođeno"</string>
- <string name="imTypeHome" msgid="6996507981044278216">"Kuća"</string>
- <string name="imTypeWork" msgid="2099668940169903123">"Posao"</string>
- <string name="imTypeOther" msgid="8068447383276219810">"Drugo"</string>
- <string name="imProtocolCustom" msgid="4437878287653764692">"Prilagođeno"</string>
+ <string name="eventTypeCustom" msgid="3257367158986466481">"Прилагођено"</string>
+ <string name="eventTypeBirthday" msgid="7770026752793912283">"Рођендан"</string>
+ <string name="eventTypeAnniversary" msgid="4684702412407916888">"Годишњица"</string>
+ <string name="eventTypeOther" msgid="530671238533887997">"Други"</string>
+ <string name="emailTypeCustom" msgid="1809435350482181786">"Прилагођено"</string>
+ <string name="emailTypeHome" msgid="1597116303154775999">"Кућа"</string>
+ <string name="emailTypeWork" msgid="2020095414401882111">"Посао"</string>
+ <string name="emailTypeOther" msgid="5131130857030897465">"Друго"</string>
+ <string name="emailTypeMobile" msgid="787155077375364230">"Мобилни"</string>
+ <string name="postalTypeCustom" msgid="5645590470242939129">"Прилагођено"</string>
+ <string name="postalTypeHome" msgid="7562272480949727912">"Кућа"</string>
+ <string name="postalTypeWork" msgid="8553425424652012826">"Посао"</string>
+ <string name="postalTypeOther" msgid="7094245413678857420">"Друго"</string>
+ <string name="imTypeCustom" msgid="5653384545085765570">"Прилагођено"</string>
+ <string name="imTypeHome" msgid="6996507981044278216">"Кућа"</string>
+ <string name="imTypeWork" msgid="2099668940169903123">"Посао"</string>
+ <string name="imTypeOther" msgid="8068447383276219810">"Друго"</string>
+ <string name="imProtocolCustom" msgid="4437878287653764692">"Прилагођено"</string>
<string name="imProtocolAim" msgid="4050198236506604378">"AIM"</string>
<string name="imProtocolMsn" msgid="2257148557766499232">"Windows Live"</string>
<string name="imProtocolYahoo" msgid="5373338758093392231">"Yahoo"</string>
@@ -885,848 +885,848 @@
<string name="imProtocolIcq" msgid="2410325380427389521">"ICQ"</string>
<string name="imProtocolJabber" msgid="7919269388889582015">"Jabber"</string>
<string name="imProtocolNetMeeting" msgid="4985002408136148256">"NetMeeting"</string>
- <string name="orgTypeWork" msgid="8684458700669564172">"Posao"</string>
- <string name="orgTypeOther" msgid="5450675258408005553">"Drugo"</string>
- <string name="orgTypeCustom" msgid="1126322047677329218">"Prilagođeno"</string>
- <string name="relationTypeCustom" msgid="282938315217441351">"Prilagođeno"</string>
- <string name="relationTypeAssistant" msgid="4057605157116589315">"Pomoćnik"</string>
- <string name="relationTypeBrother" msgid="7141662427379247820">"Brat"</string>
- <string name="relationTypeChild" msgid="9076258911292693601">"Dete"</string>
- <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"Nevenčani partner"</string>
- <string name="relationTypeFather" msgid="3856225062864790596">"Otac"</string>
- <string name="relationTypeFriend" msgid="3192092625893980574">"Prijatelj"</string>
- <string name="relationTypeManager" msgid="2272860813153171857">"Menadžer"</string>
- <string name="relationTypeMother" msgid="2331762740982699460">"Majka"</string>
- <string name="relationTypeParent" msgid="4177920938333039882">"Roditelj"</string>
- <string name="relationTypePartner" msgid="4018017075116766194">"Partner"</string>
- <string name="relationTypeReferredBy" msgid="5285082289602849400">"Uputio/la"</string>
- <string name="relationTypeRelative" msgid="3396498519818009134">"Rođak"</string>
- <string name="relationTypeSister" msgid="3721676005094140671">"Sestra"</string>
- <string name="relationTypeSpouse" msgid="6916682664436031703">"Suprug/a"</string>
- <string name="sipAddressTypeCustom" msgid="6283889809842649336">"Prilagođeno"</string>
- <string name="sipAddressTypeHome" msgid="5918441930656878367">"Početna"</string>
- <string name="sipAddressTypeWork" msgid="7873967986701216770">"Posao"</string>
- <string name="sipAddressTypeOther" msgid="6317012577345187275">"Drugi"</string>
- <string name="quick_contacts_not_available" msgid="1262709196045052223">"Nije pronađena nijedna aplikacija za prikaz ovog kontakta."</string>
- <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"Unesite PIN kôd"</string>
- <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"Unesite PUK i novi PIN kôd"</string>
- <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"PUK kôd"</string>
- <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"Novi PIN kôd"</string>
- <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"Dodirnite za unos lozinke"</font></string>
- <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Otkucajte lozinku da biste otključali"</string>
- <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Unesite PIN za otključavanje"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"PIN kôd je netačan."</string>
- <string name="keyguard_label_text" msgid="3841953694564168384">"Da biste otključali, pritisnite „Meni“, a zatim 0."</string>
- <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Broj za hitne slučajeve"</string>
- <string name="lockscreen_carrier_default" msgid="6192313772955399160">"Mobilna mreža nije dostupna"</string>
- <string name="lockscreen_screen_locked" msgid="7364905540516041817">"Ekran je zaključan."</string>
- <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pritisnite „Meni“ da biste otključali telefon ili uputite hitan poziv."</string>
- <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Pritisnite „Meni“ za otključavanje."</string>
- <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Unesite šablon za otključavanje"</string>
- <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Hitne službe"</string>
- <string name="lockscreen_return_to_call" msgid="3156883574692006382">"Nazad na poziv"</string>
- <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Tačno!"</string>
- <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Probajte ponovo"</string>
- <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Probajte ponovo"</string>
- <string name="lockscreen_storage_locked" msgid="634993789186443380">"Otključaj za sve funkcije i podatke"</string>
- <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Premašen je najveći dozvoljeni broj pokušaja Otključavanja licem"</string>
- <string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"Nema SIM kartice"</string>
- <string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"U tabletu nema SIM kartice."</string>
- <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"Nema SIM kartice u Android TV uređaju."</string>
- <string name="lockscreen_missing_sim_message" product="default" msgid="1408695081255172556">"U telefon nije umetnuta SIM kartica."</string>
- <string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"Umetnite SIM karticu."</string>
- <string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"SIM nedostaje ili ne može da se pročita. Umetnite SIM karticu."</string>
- <string name="lockscreen_permanent_disabled_sim_message_short" msgid="3812893366715730539">"SIM kartica je neupotrebljiva."</string>
- <string name="lockscreen_permanent_disabled_sim_instructions" msgid="4358929052509450807">"SIM kartica je trajno onemogućena.\n Obratite se dobavljaču usluge bežične mreže da biste dobili drugu SIM karticu."</string>
- <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"Prethodna pesma"</string>
- <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"Sledeća pesma"</string>
- <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Pauza"</string>
- <string name="lockscreen_transport_play_description" msgid="106868788691652733">"Pusti"</string>
- <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Zaustavi"</string>
- <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Premotaj unazad"</string>
- <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Premotaj unapred"</string>
- <string name="emergency_calls_only" msgid="3057351206678279851">"Samo hitni pozivi"</string>
- <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Mreža je zaključana"</string>
- <string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM kartica je zaključana PUK kodom."</string>
- <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Pogledajte Korisnički vodič ili kontaktirajte Korisničku podršku."</string>
- <string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"SIM kartica je zaključana."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"Otključavanje SIM kartice…"</string>
- <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste nepravilno nacrtali šablon za otključavanje. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
- <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste pogrešno uneli lozinku. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste pogrešno uneli PIN. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste netačno uneli šablon za otključavanje. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> nesupešna(ih) pokušaja, od vas će biti zatraženo da otključate tablet pomoću podataka za prijavljivanje na Google.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunde/i."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još puta (<xliff:g id="NUMBER_1">%2$d</xliff:g>), zatražićemo da otključate telefon pomoću Android TV uređaja.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"<xliff:g id="NUMBER_0">%1$d</xliff:g> puta ste netačno uneli šablon za otključavanje. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> nesupešna(ih) pokušaja, od vas će biti zatraženo da otključate telefon pomoću podataka za prijavljivanje na Google.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunde/i."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Nepravilno ste pokušali da otključate tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još neuspešnih pokušaja (<xliff:g id="NUMBER_1">%2$d</xliff:g>) tablet će biti resetovan na fabrička podešavanja i svi korisnički podaci će biti izgubljeni."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Broj vaših neuspešnih pokušaja da otključate Android TV uređaj: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Broj preostalih neuspešnih pokušaja posle kojih će se Android TV resetovati na fabrička podešavanja i svi podaci korisnika će biti izgubljeni: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Neispravno ste pokušali da otključate telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još neuspešnih pokušaja (<xliff:g id="NUMBER_1">%2$d</xliff:g>) telefon će biti resetovan na fabrička podešavanja i svi korisnički podaci će biti izgubljeni."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Neispravno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Tablet će sada biti vraćen na podrazumevana fabrička podešavanja."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Broj vaših neuspešnih pokušaja da otključate Android TV uređaj: <xliff:g id="NUMBER">%d</xliff:g>. Android TV uređaj će se sada resetovati na fabrička podešavanja."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Neispravno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Telefon će sada biti vraćen na podrazumevana fabrička podešavanja."</string>
- <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Probajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> sekunde/i."</string>
- <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Zaboravili ste šablon?"</string>
- <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Otključavanje naloga"</string>
- <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"Previše pokušaja unosa šablona"</string>
- <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Da biste otključali, prijavite se pomoću Google naloga."</string>
- <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"Korisničko ime (imejl adresa)"</string>
- <string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"Lozinka"</string>
- <string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"Prijavi me"</string>
- <string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"Nevažeće korisničko ime ili lozinka."</string>
- <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"Zaboravili ste korisničko ime ili lozinku?\nPosetite adresu "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"Proveravanje..."</string>
- <string name="lockscreen_unlock_label" msgid="4648257878373307582">"Otključaj"</string>
- <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"Uključi zvuk"</string>
- <string name="lockscreen_sound_off_label" msgid="2331496559245450053">"Isključi zvuk"</string>
- <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"Obrazac je započet"</string>
- <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"Obrazac je obrisan"</string>
- <string name="lockscreen_access_pattern_cell_added" msgid="6746676335293144163">"Ćelija je dodata"</string>
- <string name="lockscreen_access_pattern_cell_added_verbose" msgid="2931364927622563465">"Ćelija <xliff:g id="CELL_INDEX">%1$s</xliff:g> je dodata"</string>
- <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"Obrazac je dovršen"</string>
- <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"Oblast šablona."</string>
- <string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"%1$s. Vidžet %2$d od %3$d."</string>
- <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"Dodaj vidžet."</string>
- <string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"Prazno"</string>
- <string name="keyguard_accessibility_unlock_area_expanded" msgid="7768634718706488951">"Oblast otključavanja je proširena."</string>
- <string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"Oblast otključavanja je skupljena."</string>
- <string name="keyguard_accessibility_widget" msgid="6776892679715699875">"Vidžet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
- <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Izbor korisnika"</string>
- <string name="keyguard_accessibility_status" msgid="6792745049712397237">"Status"</string>
- <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Kamera"</string>
- <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Kontrole za medije"</string>
- <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Započela je promena redosleda vidžeta."</string>
- <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Promena redosleda vidžeta je završena."</string>
- <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Vidžet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> je izbrisan."</string>
- <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Proširi oblast otključavanja."</string>
- <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Otključavanje prevlačenjem."</string>
- <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Otključavanje šablonom."</string>
- <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Otključavanje licem."</string>
- <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Otključavanje PIN-om."</string>
- <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"Otključava SIM karticu PIN-om."</string>
- <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"Otključava SIM karticu PUK-om."</string>
- <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"Otključavanje lozinkom."</string>
- <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Oblast šablona."</string>
- <string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"Oblast prevlačenja."</string>
+ <string name="orgTypeWork" msgid="8684458700669564172">"Посао"</string>
+ <string name="orgTypeOther" msgid="5450675258408005553">"Друго"</string>
+ <string name="orgTypeCustom" msgid="1126322047677329218">"Прилагођено"</string>
+ <string name="relationTypeCustom" msgid="282938315217441351">"Прилагођено"</string>
+ <string name="relationTypeAssistant" msgid="4057605157116589315">"Помоћник"</string>
+ <string name="relationTypeBrother" msgid="7141662427379247820">"Брат"</string>
+ <string name="relationTypeChild" msgid="9076258911292693601">"Дете"</string>
+ <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"Невенчани партнер"</string>
+ <string name="relationTypeFather" msgid="3856225062864790596">"Отац"</string>
+ <string name="relationTypeFriend" msgid="3192092625893980574">"Пријатељ"</string>
+ <string name="relationTypeManager" msgid="2272860813153171857">"Менаџер"</string>
+ <string name="relationTypeMother" msgid="2331762740982699460">"Мајка"</string>
+ <string name="relationTypeParent" msgid="4177920938333039882">"Родитељ"</string>
+ <string name="relationTypePartner" msgid="4018017075116766194">"Партнер"</string>
+ <string name="relationTypeReferredBy" msgid="5285082289602849400">"Упутио/ла"</string>
+ <string name="relationTypeRelative" msgid="3396498519818009134">"Рођак"</string>
+ <string name="relationTypeSister" msgid="3721676005094140671">"Сестра"</string>
+ <string name="relationTypeSpouse" msgid="6916682664436031703">"Супруг/а"</string>
+ <string name="sipAddressTypeCustom" msgid="6283889809842649336">"Прилагођено"</string>
+ <string name="sipAddressTypeHome" msgid="5918441930656878367">"Почетна"</string>
+ <string name="sipAddressTypeWork" msgid="7873967986701216770">"Посао"</string>
+ <string name="sipAddressTypeOther" msgid="6317012577345187275">"Други"</string>
+ <string name="quick_contacts_not_available" msgid="1262709196045052223">"Није пронађена ниједна апликација за приказ овог контакта."</string>
+ <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"Унесите PIN кôд"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"Унесите PUK и нови PIN кôд"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"PUK кôд"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"Нови PIN кôд"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"Додирните за унос лозинке"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Откуцајте лозинку да бисте откључали"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Унесите PIN за откључавање"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"PIN кôд је нетачан."</string>
+ <string name="keyguard_label_text" msgid="3841953694564168384">"Да бисте откључали, притисните „Мени“, а затим 0."</string>
+ <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Број за хитне случајеве"</string>
+ <string name="lockscreen_carrier_default" msgid="6192313772955399160">"Мобилна мрежа није доступна"</string>
+ <string name="lockscreen_screen_locked" msgid="7364905540516041817">"Екран је закључан."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Притисните „Мени“ да бисте откључали телефон или упутите хитан позив."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Притисните „Мени“ за откључавање."</string>
+ <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Унесите шаблон за откључавање"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Хитне службе"</string>
+ <string name="lockscreen_return_to_call" msgid="3156883574692006382">"Назад на позив"</string>
+ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Тачно!"</string>
+ <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Пробајте поново"</string>
+ <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Пробајте поново"</string>
+ <string name="lockscreen_storage_locked" msgid="634993789186443380">"Откључај за све функције и податке"</string>
+ <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Премашен је највећи дозвољени број покушаја Откључавања лицем"</string>
+ <string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"Нема SIM картице"</string>
+ <string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"У таблету нема SIM картице."</string>
+ <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"Нема SIM картице у Android TV уређају."</string>
+ <string name="lockscreen_missing_sim_message" product="default" msgid="1408695081255172556">"У телефон није уметнута SIM картица."</string>
+ <string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"Уметните SIM картицу."</string>
+ <string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"SIM недостаје или не може да се прочита. Уметните SIM картицу."</string>
+ <string name="lockscreen_permanent_disabled_sim_message_short" msgid="3812893366715730539">"SIM картица је неупотребљива."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="4358929052509450807">"SIM картица је трајно онемогућена.\n Обратите се добављачу услуге бежичне мреже да бисте добили другу SIM картицу."</string>
+ <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"Претходна песма"</string>
+ <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"Следећа песма"</string>
+ <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Пауза"</string>
+ <string name="lockscreen_transport_play_description" msgid="106868788691652733">"Пусти"</string>
+ <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Заустави"</string>
+ <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Премотај уназад"</string>
+ <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Премотај унапред"</string>
+ <string name="emergency_calls_only" msgid="3057351206678279851">"Само хитни позиви"</string>
+ <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Мрежа је закључана"</string>
+ <string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM картица је закључана PUK кодом."</string>
+ <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Погледајте Кориснички водич или контактирајте Корисничку подршку."</string>
+ <string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"SIM картица је закључана."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"Откључавање SIM картице…"</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте неправилно нацртали шаблон за откључавање. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+ <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте погрешно унели лозинку. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте погрешно унели PIN. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу података за пријављивање на Google.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде/и."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још пута (<xliff:g id="NUMBER_1">%2$d</xliff:g>), затражићемо да откључате телефон помоћу Android TV уређаја.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу података за пријављивање на Google.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунде/и."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Неправилно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%2$d</xliff:g>) таблет ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Број ваших неуспешних покушаја да откључате Android TV уређај: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Број преосталих неуспешних покушаја после којих ће се Android TV ресетовати на фабричка подешавања и сви подаци корисника ће бити изгубљени: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Неисправно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%2$d</xliff:g>) телефон ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Неисправно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Таблет ће сада бити враћен на подразумевана фабричка подешавања."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Број ваших неуспешних покушаја да откључате Android TV уређај: <xliff:g id="NUMBER">%d</xliff:g>. Android TV уређај ће се сада ресетовати на фабричка подешавања."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Неисправно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Телефон ће сада бити враћен на подразумевана фабричка подешавања."</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Пробајте поново за <xliff:g id="NUMBER">%d</xliff:g> секунде/и."</string>
+ <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Заборавили сте шаблон?"</string>
+ <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Откључавање налога"</string>
+ <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"Превише покушаја уноса шаблона"</string>
+ <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Да бисте откључали, пријавите се помоћу Google налога."</string>
+ <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"Корисничко име (имејл адреса)"</string>
+ <string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"Лозинка"</string>
+ <string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"Пријави ме"</string>
+ <string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"Неважеће корисничко име или лозинка."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"Заборавили сте корисничко име или лозинку?\nПосетите адресу "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"Проверавање..."</string>
+ <string name="lockscreen_unlock_label" msgid="4648257878373307582">"Откључај"</string>
+ <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"Укључи звук"</string>
+ <string name="lockscreen_sound_off_label" msgid="2331496559245450053">"Искључи звук"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"Образац је започет"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"Образац је обрисан"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6746676335293144163">"Ћелија је додата"</string>
+ <string name="lockscreen_access_pattern_cell_added_verbose" msgid="2931364927622563465">"Ћелија <xliff:g id="CELL_INDEX">%1$s</xliff:g> је додата"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"Образац је довршен"</string>
+ <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"Област шаблона."</string>
+ <string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"%1$s. Виџет %2$d од %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"Додај виџет."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"Празно"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="7768634718706488951">"Област откључавања је проширена."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"Област откључавања је скупљена."</string>
+ <string name="keyguard_accessibility_widget" msgid="6776892679715699875">"Виџет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Избор корисника"</string>
+ <string name="keyguard_accessibility_status" msgid="6792745049712397237">"Статус"</string>
+ <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Камера"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Контроле за медије"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Започела је промена редоследа виџета."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Промена редоследа виџета је завршена."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Виџет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> је избрисан."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Прошири област откључавања."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Откључавање превлачењем."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Откључавање шаблоном."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Откључавање лицем."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Откључавање PIN-ом."</string>
+ <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"Откључава SIM картицу PIN-ом."</string>
+ <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"Откључава SIM картицу PUK-ом."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"Откључавање лозинком."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Област шаблона."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"Област превлачења."</string>
<string name="password_keyboard_label_symbol_key" msgid="2716255580853511949">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="5294837425652726684">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="8528261816395508841">"ALT"</string>
- <string name="granularity_label_character" msgid="8903387663153706317">"znak"</string>
- <string name="granularity_label_word" msgid="3686589158760620518">"reč"</string>
- <string name="granularity_label_link" msgid="9007852307112046526">"link"</string>
- <string name="granularity_label_line" msgid="376204904280620221">"red"</string>
- <string name="factorytest_failed" msgid="3190979160945298006">"Fabričko testiranje nije uspelo"</string>
- <string name="factorytest_not_system" msgid="5658160199925519869">"Radnja FACTORY_TEST je podržana samo za pakete instalirane u folderu /system/app."</string>
- <string name="factorytest_no_action" msgid="339252838115675515">"Nije pronađen nijedan paket koji obezbeđuje radnju FACTORY_TEST."</string>
- <string name="factorytest_reboot" msgid="2050147445567257365">"Restartuj"</string>
- <string name="js_dialog_title" msgid="7464775045615023241">"Na stranici na adresi „<xliff:g id="TITLE">%s</xliff:g>“ piše:"</string>
+ <string name="granularity_label_character" msgid="8903387663153706317">"знак"</string>
+ <string name="granularity_label_word" msgid="3686589158760620518">"реч"</string>
+ <string name="granularity_label_link" msgid="9007852307112046526">"линк"</string>
+ <string name="granularity_label_line" msgid="376204904280620221">"ред"</string>
+ <string name="factorytest_failed" msgid="3190979160945298006">"Фабричко тестирање није успело"</string>
+ <string name="factorytest_not_system" msgid="5658160199925519869">"Радња FACTORY_TEST је подржана само за пакете инсталиране у фолдеру /system/app."</string>
+ <string name="factorytest_no_action" msgid="339252838115675515">"Није пронађен ниједан пакет који обезбеђује радњу FACTORY_TEST."</string>
+ <string name="factorytest_reboot" msgid="2050147445567257365">"Рестартуј"</string>
+ <string name="js_dialog_title" msgid="7464775045615023241">"На страници на адреси „<xliff:g id="TITLE">%s</xliff:g>“ пише:"</string>
<string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
- <string name="js_dialog_before_unload_title" msgid="7012587995876771246">"Potvrda navigacije"</string>
- <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"Zatvori ovu stranicu"</string>
- <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"Ostani na ovoj stranici"</string>
- <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nDa li stvarno želite da napustite ovu stranicu?"</string>
- <string name="save_password_label" msgid="9161712335355510035">"Potvrda"</string>
- <string name="double_tap_toast" msgid="7065519579174882778">"Savet: Dodirnite dvaput da biste uvećali i umanjili prikaz."</string>
- <string name="autofill_this_form" msgid="3187132440451621492">"Autom. pop."</string>
- <string name="setup_autofill" msgid="5431369130866618567">"Podeš. aut. pop."</string>
- <string name="autofill_window_title" msgid="4379134104008111961">"Automatski popunjava <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
+ <string name="js_dialog_before_unload_title" msgid="7012587995876771246">"Потврда навигације"</string>
+ <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"Затвори ову страницу"</string>
+ <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"Остани на овој страници"</string>
+ <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nДа ли стварно желите да напустите ову страницу?"</string>
+ <string name="save_password_label" msgid="9161712335355510035">"Потврда"</string>
+ <string name="double_tap_toast" msgid="7065519579174882778">"Савет: Додирните двапут да бисте увећали и умањили приказ."</string>
+ <string name="autofill_this_form" msgid="3187132440451621492">"Аутом. поп."</string>
+ <string name="setup_autofill" msgid="5431369130866618567">"Подеш. аут. поп."</string>
+ <string name="autofill_window_title" msgid="4379134104008111961">"Аутоматски попуњава <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
<string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string>
<string name="autofill_address_summary_name_format" msgid="3402882515222673691">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="760522655085707045">", "</string>
<string name="autofill_address_summary_format" msgid="8417010069362125194">"$1$2$3"</string>
- <string name="autofill_province" msgid="3676846437741893159">"Pokrajina"</string>
- <string name="autofill_postal_code" msgid="7034789388968295591">"Poštanski broj"</string>
- <string name="autofill_state" msgid="3341725337190434069">"Država"</string>
- <string name="autofill_zip_code" msgid="1315503730274962450">"Poštanski broj"</string>
- <string name="autofill_county" msgid="7781382735643492173">"Okrug"</string>
- <string name="autofill_island" msgid="5367139008536593734">"Ostrvo"</string>
- <string name="autofill_district" msgid="6428712062213557327">"Distrikt"</string>
- <string name="autofill_department" msgid="9047276226873531529">"Odeljenje"</string>
- <string name="autofill_prefecture" msgid="7267397763720241872">"Prefektura"</string>
- <string name="autofill_parish" msgid="6847960518334530198">"Parohija"</string>
- <string name="autofill_area" msgid="8289022370678448983">"Oblast"</string>
- <string name="autofill_emirate" msgid="2544082046790551168">"Emirat"</string>
- <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"čitanje veb obeleživača i istorije"</string>
- <string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Dozvoljava aplikaciji da čita istoriju svih URL adresa koje su posećene pomoću Pregledača, kao i sve obeleživače u Pregledaču. Napomena: Ova dozvola se možda na primenjuje na pregledače treće strane i druge aplikacije sa mogućnošću veb pregledanja."</string>
- <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"pisanje veb obeleživača i istorije"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Dozvoljava aplikaciji da menja istoriju Pregledača ili obeleživače uskladištene na tabletu. Ovo može da omogući aplikaciji da briše ili menja podatke Pregledača. Napomena: Ova dozvola se možda na primenjuje na pregledače treće strane i druge aplikacije sa mogućnošću veb pregledanja."</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Dozvoljava aplikaciji da menja istoriju pregledača ili obeleživače koji se čuvaju na Android TV uređaju. Ovo može da omogući aplikaciji da briše ili menja podatke pregledača. Napomena: ova dozvola se možda ne primenjuje na pregledače treće strane ni druge aplikacije sa mogućnostima veb-pregledanja."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Dozvoljava aplikaciji da menja istoriju Pregledača ili obeleživače uskladištene na telefonu. Ovo može da omogući aplikaciji da briše ili menja podatke Pregledača. Napomena: Ova dozvola se možda na primenjuje na pregledače treće strane i druge aplikacije sa mogućnošću veb pregledanja."</string>
- <string name="permlab_setAlarm" msgid="1158001610254173567">"podešavanje alarma"</string>
- <string name="permdesc_setAlarm" msgid="2185033720060109640">"Dozvoljava aplikaciji da podesi alarm u instaliranoj aplikaciji budilnika. Neke aplikacije budilnika možda ne primenjuju ovu funkciju."</string>
- <string name="permlab_addVoicemail" msgid="4770245808840814471">"dodavanje govorne pošte"</string>
- <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Dozvoljava aplikaciji da dodaje poruke u prijemno sanduče govorne pošte."</string>
- <string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"izmena dozvola za geografske lokacije Pregledača"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Dozvoljava aplikaciji da izmeni dozvole Pregledača za utvrđivanje geografske lokacije. Zlonamerne aplikacije to mogu da zloupotrebe i iskoriste za slanje informacija o lokaciji nasumičnim veb-sajtovima."</string>
- <string name="save_password_message" msgid="2146409467245462965">"Želite li da pregledač zapamti ovu lozinku?"</string>
- <string name="save_password_notnow" msgid="2878327088951240061">"Ne sada"</string>
- <string name="save_password_remember" msgid="6490888932657708341">"Zapamti"</string>
- <string name="save_password_never" msgid="6776808375903410659">"Nikad"</string>
- <string name="open_permission_deny" msgid="5136793905306987251">"Nemate dozvolu da otvorite ovu stranicu."</string>
- <string name="text_copied" msgid="2531420577879738860">"Tekst je kopiran u privremenu memoriju."</string>
- <string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila podatke iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
- <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prelepio/la iz privremene memorije"</string>
- <string name="pasted_text" msgid="4298871641549173733">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila tekst koji ste kopirali"</string>
- <string name="pasted_image" msgid="4729097394781491022">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila sliku koju ste kopirali"</string>
- <string name="pasted_content" msgid="646276353060777131">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila sadržaj koji ste kopirali"</string>
- <string name="more_item_label" msgid="7419249600215749115">"Još"</string>
- <string name="prepend_shortcut_label" msgid="1743716737502867951">"Meni+"</string>
+ <string name="autofill_province" msgid="3676846437741893159">"Покрајина"</string>
+ <string name="autofill_postal_code" msgid="7034789388968295591">"Поштански број"</string>
+ <string name="autofill_state" msgid="3341725337190434069">"Држава"</string>
+ <string name="autofill_zip_code" msgid="1315503730274962450">"Поштански број"</string>
+ <string name="autofill_county" msgid="7781382735643492173">"Округ"</string>
+ <string name="autofill_island" msgid="5367139008536593734">"Острво"</string>
+ <string name="autofill_district" msgid="6428712062213557327">"Дистрикт"</string>
+ <string name="autofill_department" msgid="9047276226873531529">"Одељење"</string>
+ <string name="autofill_prefecture" msgid="7267397763720241872">"Префектура"</string>
+ <string name="autofill_parish" msgid="6847960518334530198">"Парохија"</string>
+ <string name="autofill_area" msgid="8289022370678448983">"Област"</string>
+ <string name="autofill_emirate" msgid="2544082046790551168">"Емират"</string>
+ <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"читање веб обележивача и историје"</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Дозвољава апликацији да чита историју свих URL адреса које су посећене помоћу Прегледача, као и све обележиваче у Прегледачу. Напомена: Ова дозвола се можда на примењује на прегледаче треће стране и друге апликације са могућношћу веб прегледања."</string>
+ <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"писање веб обележивача и историје"</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Дозвољава апликацији да мења историју Прегледача или обележиваче ускладиштене на таблету. Ово може да омогући апликацији да брише или мења податке Прегледача. Напомена: Ова дозвола се можда на примењује на прегледаче треће стране и друге апликације са могућношћу веб прегледања."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Дозвољава апликацији да мења историју прегледача или обележиваче који се чувају на Android TV уређају. Ово може да омогући апликацији да брише или мења податке прегледача. Напомена: ова дозвола се можда не примењује на прегледаче треће стране ни друге апликације са могућностима веб-прегледања."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Дозвољава апликацији да мења историју Прегледача или обележиваче ускладиштене на телефону. Ово може да омогући апликацији да брише или мења податке Прегледача. Напомена: Ова дозвола се можда на примењује на прегледаче треће стране и друге апликације са могућношћу веб прегледања."</string>
+ <string name="permlab_setAlarm" msgid="1158001610254173567">"подешавање аларма"</string>
+ <string name="permdesc_setAlarm" msgid="2185033720060109640">"Дозвољава апликацији да подеси аларм у инсталираној апликацији будилника. Неке апликације будилника можда не примењују ову функцију."</string>
+ <string name="permlab_addVoicemail" msgid="4770245808840814471">"додавање говорне поште"</string>
+ <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Дозвољава апликацији да додаје поруке у пријемно сандуче говорне поште."</string>
+ <string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"измена дозвола за географске локације Прегледача"</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Дозвољава апликацији да измени дозволе Прегледача за утврђивање географске локације. Злонамерне апликације то могу да злоупотребе и искористе за слање информација о локацији насумичним веб-сајтовима."</string>
+ <string name="save_password_message" msgid="2146409467245462965">"Желите ли да прегледач запамти ову лозинку?"</string>
+ <string name="save_password_notnow" msgid="2878327088951240061">"Не сада"</string>
+ <string name="save_password_remember" msgid="6490888932657708341">"Запамти"</string>
+ <string name="save_password_never" msgid="6776808375903410659">"Никад"</string>
+ <string name="open_permission_deny" msgid="5136793905306987251">"Немате дозволу да отворите ову страницу."</string>
+ <string name="text_copied" msgid="2531420577879738860">"Текст је копиран у привремену меморију."</string>
+ <string name="pasted_from_app" msgid="5627698450808256545">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила податке из апликације <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
+ <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је прелепио/ла из привремене меморије"</string>
+ <string name="pasted_text" msgid="4298871641549173733">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила текст који сте копирали"</string>
+ <string name="pasted_image" msgid="4729097394781491022">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила слику коју сте копирали"</string>
+ <string name="pasted_content" msgid="646276353060777131">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила садржај који сте копирали"</string>
+ <string name="more_item_label" msgid="7419249600215749115">"Још"</string>
+ <string name="prepend_shortcut_label" msgid="1743716737502867951">"Мени+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
<string name="menu_ctrl_shortcut_label" msgid="131911133027196485">"Ctrl+"</string>
<string name="menu_alt_shortcut_label" msgid="343761069945250991">"Alt+"</string>
<string name="menu_shift_shortcut_label" msgid="5443936876111232346">"Shift+"</string>
<string name="menu_sym_shortcut_label" msgid="4037566049061218776">"Sym+"</string>
<string name="menu_function_shortcut_label" msgid="2367112760987662566">"Function+"</string>
- <string name="menu_space_shortcut_label" msgid="5949311515646872071">"razmak"</string>
+ <string name="menu_space_shortcut_label" msgid="5949311515646872071">"размак"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
- <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"izbriši"</string>
- <string name="search_go" msgid="2141477624421347086">"Pretraži"</string>
- <string name="search_hint" msgid="455364685740251925">"Pretražite…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"Pretraži"</string>
- <string name="searchview_description_query" msgid="7430242366971716338">"Upit za pretragu"</string>
- <string name="searchview_description_clear" msgid="1989371719192982900">"Obriši upit"</string>
- <string name="searchview_description_submit" msgid="6771060386117334686">"Pošalji upit"</string>
- <string name="searchview_description_voice" msgid="42360159504884679">"Glasovna pretraga"</string>
- <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Omogućiti Istraživanje dodirom?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi da omogući Istraživanje dodirom. Kada je Istraživanje dodirom uključeno, možete da čujete ili vidite opise stavke na koju ste stavili prst ili da komunicirate sa tabletom pomoću pokreta."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi da omogući Istraživanje dodirom. Kada je Istraživanje dodirom uključeno, možete da čujete ili vidite opise stavke na koju ste stavili prst ili da komunicirate sa telefonom pomoću pokreta."</string>
- <string name="oneMonthDurationPast" msgid="4538030857114635777">"Pre mesec dana"</string>
- <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Pre mesec dana"</string>
- <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{Poslednji # dan}one{Poslednji # dan}few{Poslednja # dana}other{Poslednjih # dana}}"</string>
- <string name="last_month" msgid="1528906781083518683">"Prošlog meseca"</string>
- <string name="older" msgid="1645159827884647400">"Starije"</string>
+ <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"избриши"</string>
+ <string name="search_go" msgid="2141477624421347086">"Претражи"</string>
+ <string name="search_hint" msgid="455364685740251925">"Претражите…"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Претражи"</string>
+ <string name="searchview_description_query" msgid="7430242366971716338">"Упит за претрагу"</string>
+ <string name="searchview_description_clear" msgid="1989371719192982900">"Обриши упит"</string>
+ <string name="searchview_description_submit" msgid="6771060386117334686">"Пошаљи упит"</string>
+ <string name="searchview_description_voice" msgid="42360159504884679">"Гласовна претрага"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Oмогућити Истраживање додиром?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> жели да омогући Истраживање додиром. Када је Истраживање додиром укључено, можете да чујете или видите описе ставке на коју сте ставили прст или да комуницирате са таблетом помоћу покрета."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> жели да омогући Истраживање додиром. Када је Истраживање додиром укључено, можете да чујете или видите описе ставке на коју сте ставили прст или да комуницирате са телефоном помоћу покрета."</string>
+ <string name="oneMonthDurationPast" msgid="4538030857114635777">"Пре месец дана"</string>
+ <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Пре месец дана"</string>
+ <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{Последњи # дан}one{Последњи # дан}few{Последња # дана}other{Последњих # дана}}"</string>
+ <string name="last_month" msgid="1528906781083518683">"Прошлог месеца"</string>
+ <string name="older" msgid="1645159827884647400">"Старије"</string>
<string name="preposition_for_date" msgid="2780767868832729599">"<xliff:g id="DATE">%s</xliff:g>"</string>
- <string name="preposition_for_time" msgid="4336835286453822053">"u <xliff:g id="TIME">%s</xliff:g>"</string>
- <string name="preposition_for_year" msgid="3149809685340130039">"u <xliff:g id="YEAR">%s</xliff:g>."</string>
- <string name="day" msgid="8394717255950176156">"dan"</string>
- <string name="days" msgid="4570879797423034973">"dana"</string>
- <string name="hour" msgid="7796325297097314653">"sat"</string>
- <string name="hours" msgid="8517014849629200683">"sata"</string>
- <string name="minute" msgid="8369209540986467610">"min"</string>
- <string name="minutes" msgid="3456532942641808971">"min"</string>
- <string name="second" msgid="9210875257112211713">"sek"</string>
- <string name="seconds" msgid="2175052687727971048">"sek"</string>
- <string name="week" msgid="907127093960923779">"nedelja"</string>
- <string name="weeks" msgid="3516247214269821391">"nedelje/a"</string>
- <string name="year" msgid="5182610307741238982">"godina"</string>
- <string name="years" msgid="5797714729103773425">"godine(a)"</string>
- <string name="now_string_shortest" msgid="3684914126941650330">"sada"</string>
- <string name="duration_minutes_shortest" msgid="5744379079540806690">"<xliff:g id="COUNT">%d</xliff:g> min"</string>
- <string name="duration_hours_shortest" msgid="1477752094141971675">"<xliff:g id="COUNT">%d</xliff:g> s"</string>
- <string name="duration_days_shortest" msgid="4083124701676227233">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
- <string name="duration_years_shortest" msgid="483982719231145618">"<xliff:g id="COUNT">%d</xliff:g> god"</string>
- <string name="duration_minutes_shortest_future" msgid="5260857299282734759">"za <xliff:g id="COUNT">%d</xliff:g> min"</string>
- <string name="duration_hours_shortest_future" msgid="2979276794547981674">"za <xliff:g id="COUNT">%d</xliff:g> s"</string>
- <string name="duration_days_shortest_future" msgid="3392722163935571543">"za <xliff:g id="COUNT">%d</xliff:g> d"</string>
- <string name="duration_years_shortest_future" msgid="5537464088352970388">"za <xliff:g id="COUNT">%d</xliff:g> god"</string>
- <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Pre # minut}one{Pre # minut}few{Pre # minuta}other{Pre # minuta}}"</string>
- <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Pre # sat}one{Pre # sat}few{Pre # sata}other{Pre # sati}}"</string>
- <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Pre # dan}one{Pre # dan}few{Pre # dana}other{Pre # dana}}"</string>
- <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{Pre # godinu}one{Pre # godinu}few{Pre # godine}other{Pre # godina}}"</string>
- <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# minut}one{# minut}few{# minuta}other{# minuta}}"</string>
- <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# sat}one{# sat}few{# sata}other{# sati}}"</string>
- <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# dan}one{# dan}few{# dana}other{# dana}}"</string>
- <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# godina}one{# godina}few{# godine}other{# godina}}"</string>
- <string name="VideoView_error_title" msgid="5750686717225068016">"Problem sa video snimkom"</string>
- <string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Ovaj video ne može da se strimuje na ovom uređaju."</string>
- <string name="VideoView_error_text_unknown" msgid="7658683339707607138">"Ne možete da pustite ovaj video."</string>
- <string name="VideoView_error_button" msgid="5138809446603764272">"Potvrdi"</string>
+ <string name="preposition_for_time" msgid="4336835286453822053">"у <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="preposition_for_year" msgid="3149809685340130039">"у <xliff:g id="YEAR">%s</xliff:g>."</string>
+ <string name="day" msgid="8394717255950176156">"дан"</string>
+ <string name="days" msgid="4570879797423034973">"дана"</string>
+ <string name="hour" msgid="7796325297097314653">"сат"</string>
+ <string name="hours" msgid="8517014849629200683">"сата"</string>
+ <string name="minute" msgid="8369209540986467610">"мин"</string>
+ <string name="minutes" msgid="3456532942641808971">"мин"</string>
+ <string name="second" msgid="9210875257112211713">"сек"</string>
+ <string name="seconds" msgid="2175052687727971048">"сек"</string>
+ <string name="week" msgid="907127093960923779">"недеља"</string>
+ <string name="weeks" msgid="3516247214269821391">"недеље/а"</string>
+ <string name="year" msgid="5182610307741238982">"година"</string>
+ <string name="years" msgid="5797714729103773425">"годинe(а)"</string>
+ <string name="now_string_shortest" msgid="3684914126941650330">"сада"</string>
+ <string name="duration_minutes_shortest" msgid="5744379079540806690">"<xliff:g id="COUNT">%d</xliff:g> мин"</string>
+ <string name="duration_hours_shortest" msgid="1477752094141971675">"<xliff:g id="COUNT">%d</xliff:g> с"</string>
+ <string name="duration_days_shortest" msgid="4083124701676227233">"<xliff:g id="COUNT">%d</xliff:g> д"</string>
+ <string name="duration_years_shortest" msgid="483982719231145618">"<xliff:g id="COUNT">%d</xliff:g> год"</string>
+ <string name="duration_minutes_shortest_future" msgid="5260857299282734759">"за <xliff:g id="COUNT">%d</xliff:g> мин"</string>
+ <string name="duration_hours_shortest_future" msgid="2979276794547981674">"за <xliff:g id="COUNT">%d</xliff:g> с"</string>
+ <string name="duration_days_shortest_future" msgid="3392722163935571543">"за <xliff:g id="COUNT">%d</xliff:g> д"</string>
+ <string name="duration_years_shortest_future" msgid="5537464088352970388">"за <xliff:g id="COUNT">%d</xliff:g> год"</string>
+ <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Пре # минут}one{Пре # минут}few{Пре # минута}other{Пре # минута}}"</string>
+ <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Пре # сат}one{Пре # сат}few{Пре # сата}other{Пре # сати}}"</string>
+ <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Пре # дан}one{Пре # дан}few{Пре # дана}other{Пре # дана}}"</string>
+ <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{Пре # годину}one{Пре # годину}few{Пре # године}other{Пре # година}}"</string>
+ <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# минут}one{# минут}few{# минута}other{# минута}}"</string>
+ <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# сат}one{# сат}few{# сата}other{# сати}}"</string>
+ <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# дан}one{# дан}few{# дана}other{# дана}}"</string>
+ <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# година}one{# година}few{# године}other{# година}}"</string>
+ <string name="VideoView_error_title" msgid="5750686717225068016">"Проблем са видео снимком"</string>
+ <string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Овај видео не може да се стримује на овом уређају."</string>
+ <string name="VideoView_error_text_unknown" msgid="7658683339707607138">"Не можете да пустите овај видео."</string>
+ <string name="VideoView_error_button" msgid="5138809446603764272">"Потврди"</string>
<string name="relative_time" msgid="8572030016028033243">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="noon" msgid="8365974533050605886">"podne"</string>
- <string name="Noon" msgid="6902418443846838189">"Podne"</string>
- <string name="midnight" msgid="3646671134282785114">"ponoć"</string>
- <string name="Midnight" msgid="8176019203622191377">"Ponoć"</string>
+ <string name="noon" msgid="8365974533050605886">"подне"</string>
+ <string name="Noon" msgid="6902418443846838189">"Подне"</string>
+ <string name="midnight" msgid="3646671134282785114">"поноћ"</string>
+ <string name="Midnight" msgid="8176019203622191377">"Поноћ"</string>
<string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
- <string name="selectAll" msgid="1532369154488982046">"Izaberi sve"</string>
- <string name="cut" msgid="2561199725874745819">"Iseci"</string>
- <string name="copy" msgid="5472512047143665218">"Kopiraj"</string>
- <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Kopiranje u privremenu memoriju nije uspelo"</string>
- <string name="paste" msgid="461843306215520225">"Nalepi"</string>
- <string name="paste_as_plain_text" msgid="7664800665823182587">"Nalepi kao običan tekst"</string>
- <string name="replace" msgid="7842675434546657444">"Zameni..."</string>
- <string name="delete" msgid="1514113991712129054">"Izbriši"</string>
- <string name="copyUrl" msgid="6229645005987260230">"Kopiraj URL adresu"</string>
- <string name="selectTextMode" msgid="3225108910999318778">"Izaberi tekst"</string>
- <string name="undo" msgid="3175318090002654673">"Opozovi"</string>
- <string name="redo" msgid="7231448494008532233">"Ponovi"</string>
- <string name="autofill" msgid="511224882647795296">"Automatsko popunjavanje"</string>
- <string name="textSelectionCABTitle" msgid="5151441579532476940">"Izbor teksta"</string>
- <string name="addToDictionary" msgid="8041821113480950096">"Dodaj u rečnik"</string>
- <string name="deleteText" msgid="4200807474529938112">"Izbriši"</string>
- <string name="inputMethod" msgid="1784759500516314751">"Metod unosa"</string>
- <string name="editTextMenuTitle" msgid="857666911134482176">"Radnje u vezi sa tekstom"</string>
- <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Nazad"</string>
- <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Promenite metod unosa"</string>
- <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Memorijski prostor je na izmaku"</string>
- <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Neke sistemske funkcije možda ne funkcionišu"</string>
- <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Nema dovoljno memorijskog prostora za sistem. Uverite se da imate 250 MB slobodnog prostora i ponovo pokrenite."</string>
- <string name="app_running_notification_title" msgid="8985999749231486569">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta"</string>
- <string name="app_running_notification_text" msgid="5120815883400228566">"Dodirnite za više informacija ili zaustavljanje aplikacije."</string>
- <string name="ok" msgid="2646370155170753815">"Potvrdi"</string>
- <string name="cancel" msgid="6908697720451760115">"Otkaži"</string>
- <string name="yes" msgid="9069828999585032361">"Potvrdi"</string>
- <string name="no" msgid="5122037903299899715">"Otkaži"</string>
- <string name="dialog_alert_title" msgid="651856561974090712">"Pažnja"</string>
- <string name="loading" msgid="3138021523725055037">"Učitava se…"</string>
- <string name="capital_on" msgid="2770685323900821829">"DA"</string>
- <string name="capital_off" msgid="7443704171014626777">"NE"</string>
- <string name="checked" msgid="9179896827054513119">"označeno je"</string>
- <string name="not_checked" msgid="7972320087569023342">"nije označeno"</string>
- <string name="selected" msgid="6614607926197755875">"izabrano"</string>
- <string name="not_selected" msgid="410652016565864475">"nije izabrano"</string>
- <string name="in_progress" msgid="2149208189184319441">"u toku"</string>
- <string name="whichApplication" msgid="5432266899591255759">"Dovrši radnju preko"</string>
- <string name="whichApplicationNamed" msgid="6969946041713975681">"Završite radnju pomoću aplikacije %1$s"</string>
- <string name="whichApplicationLabel" msgid="7852182961472531728">"Završi radnju"</string>
- <string name="whichViewApplication" msgid="5733194231473132945">"Otvorite pomoću"</string>
- <string name="whichViewApplicationNamed" msgid="415164730629690105">"Otvorite pomoću aplikacije %1$s"</string>
- <string name="whichViewApplicationLabel" msgid="7367556735684742409">"Otvori"</string>
- <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Otvarajte <xliff:g id="HOST">%1$s</xliff:g> linkove pomoću"</string>
- <string name="whichOpenLinksWith" msgid="1120936181362907258">"Otvaraj linkove pomoću"</string>
- <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Otvarajte linkove pomoću aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
- <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Otvarajte <xliff:g id="HOST">%1$s</xliff:g> linkove pomoću aplikacije <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
- <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"Dozvoli pristup"</string>
- <string name="whichEditApplication" msgid="6191568491456092812">"Izmenite pomoću"</string>
- <string name="whichEditApplicationNamed" msgid="8096494987978521514">"Izmenite pomoću aplikacije %1$s"</string>
- <string name="whichEditApplicationLabel" msgid="1463288652070140285">"Izmeni"</string>
- <string name="whichSendApplication" msgid="4143847974460792029">"Delite"</string>
- <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Delite pomoću aplikacije %1$s"</string>
- <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Deli"</string>
- <string name="whichSendToApplication" msgid="77101541959464018">"Pošaljite pomoću:"</string>
- <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Pošaljite pomoću: %1$s"</string>
- <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Pošalji"</string>
- <string name="whichHomeApplication" msgid="8276350727038396616">"Izaberite aplikaciju za početnu stranicu"</string>
- <string name="whichHomeApplicationNamed" msgid="5855990024847433794">"Koristite %1$s za početnu"</string>
- <string name="whichHomeApplicationLabel" msgid="8907334282202933959">"Snimite sliku"</string>
- <string name="whichImageCaptureApplication" msgid="2737413019463215284">"Snimite sliku pomoću aplikacije"</string>
- <string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Snimite sliku pomoću aplikacije %1$s"</string>
- <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Snimite sliku"</string>
- <string name="alwaysUse" msgid="3153558199076112903">"Podrazumevano koristi za ovu radnju."</string>
- <string name="use_a_different_app" msgid="4987790276170972776">"Koristite drugu aplikaciju"</string>
- <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Obrišite podrazumevano podešavanje u meniju Podešavanja sistema > Aplikacije > Preuzeto."</string>
- <string name="chooseActivity" msgid="8563390197659779956">"Izaberite radnju"</string>
- <string name="chooseUsbActivity" msgid="2096269989990986612">"Izbor aplikacije za USB uređaj"</string>
- <string name="noApplications" msgid="1186909265235544019">"Nijedna aplikacija ne može da obavlja ovu radnju."</string>
- <string name="aerr_application" msgid="4090916809370389109">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> je zaustavljena"</string>
- <string name="aerr_process" msgid="4268018696970966407">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> je zaustavljen"</string>
- <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja"</string>
- <string name="aerr_process_repeated" msgid="1153152413537954974">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se stalno zaustavlja"</string>
- <string name="aerr_restart" msgid="2789618625210505419">"Ponovo otvori aplikaciju"</string>
- <string name="aerr_report" msgid="3095644466849299308">"Pošaljite povratne informacije"</string>
- <string name="aerr_close" msgid="3398336821267021852">"Zatvori"</string>
- <string name="aerr_mute" msgid="2304972923480211376">"Ignoriši dok se uređaj ne pokrene ponovo"</string>
- <string name="aerr_wait" msgid="3198677780474548217">"Čekaj"</string>
- <string name="aerr_close_app" msgid="8318883106083050970">"Zatvori aplikaciju"</string>
+ <string name="selectAll" msgid="1532369154488982046">"Изабери све"</string>
+ <string name="cut" msgid="2561199725874745819">"Исеци"</string>
+ <string name="copy" msgid="5472512047143665218">"Копирај"</string>
+ <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Копирање у привремену меморију није успело"</string>
+ <string name="paste" msgid="461843306215520225">"Налепи"</string>
+ <string name="paste_as_plain_text" msgid="7664800665823182587">"Налепи као обичан текст"</string>
+ <string name="replace" msgid="7842675434546657444">"Замени..."</string>
+ <string name="delete" msgid="1514113991712129054">"Избриши"</string>
+ <string name="copyUrl" msgid="6229645005987260230">"Копирај URL адресу"</string>
+ <string name="selectTextMode" msgid="3225108910999318778">"Изабери текст"</string>
+ <string name="undo" msgid="3175318090002654673">"Опозови"</string>
+ <string name="redo" msgid="7231448494008532233">"Понови"</string>
+ <string name="autofill" msgid="511224882647795296">"Аутоматско попуњавање"</string>
+ <string name="textSelectionCABTitle" msgid="5151441579532476940">"Избор текста"</string>
+ <string name="addToDictionary" msgid="8041821113480950096">"Додај у речник"</string>
+ <string name="deleteText" msgid="4200807474529938112">"Избриши"</string>
+ <string name="inputMethod" msgid="1784759500516314751">"Метод уноса"</string>
+ <string name="editTextMenuTitle" msgid="857666911134482176">"Радње у вези са текстом"</string>
+ <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string>
+ <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Промените метод уноса"</string>
+ <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Меморијски простор је на измаку"</string>
+ <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Неке системске функције можда не функционишу"</string>
+ <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Нема довољно меморијског простора за систем. Уверите се да имате 250 MB слободног простора и поново покрените."</string>
+ <string name="app_running_notification_title" msgid="8985999749231486569">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је покренута"</string>
+ <string name="app_running_notification_text" msgid="5120815883400228566">"Додирните за више информација или заустављање апликације."</string>
+ <string name="ok" msgid="2646370155170753815">"Потврди"</string>
+ <string name="cancel" msgid="6908697720451760115">"Откажи"</string>
+ <string name="yes" msgid="9069828999585032361">"Потврди"</string>
+ <string name="no" msgid="5122037903299899715">"Откажи"</string>
+ <string name="dialog_alert_title" msgid="651856561974090712">"Пажња"</string>
+ <string name="loading" msgid="3138021523725055037">"Учитава се…"</string>
+ <string name="capital_on" msgid="2770685323900821829">"ДА"</string>
+ <string name="capital_off" msgid="7443704171014626777">"НЕ"</string>
+ <string name="checked" msgid="9179896827054513119">"означено је"</string>
+ <string name="not_checked" msgid="7972320087569023342">"није означено"</string>
+ <string name="selected" msgid="6614607926197755875">"изабрано"</string>
+ <string name="not_selected" msgid="410652016565864475">"није изабрано"</string>
+ <string name="in_progress" msgid="2149208189184319441">"у току"</string>
+ <string name="whichApplication" msgid="5432266899591255759">"Доврши радњу преко"</string>
+ <string name="whichApplicationNamed" msgid="6969946041713975681">"Завршите радњу помоћу апликације %1$s"</string>
+ <string name="whichApplicationLabel" msgid="7852182961472531728">"Заврши радњу"</string>
+ <string name="whichViewApplication" msgid="5733194231473132945">"Отворите помоћу"</string>
+ <string name="whichViewApplicationNamed" msgid="415164730629690105">"Отворите помоћу апликације %1$s"</string>
+ <string name="whichViewApplicationLabel" msgid="7367556735684742409">"Отвори"</string>
+ <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Отварајте <xliff:g id="HOST">%1$s</xliff:g> линкове помоћу"</string>
+ <string name="whichOpenLinksWith" msgid="1120936181362907258">"Отварај линкове помоћу"</string>
+ <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Отварајте линкове помоћу апликације <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+ <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Отварајте <xliff:g id="HOST">%1$s</xliff:g> линкове помоћу апликације <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+ <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"Дозволи приступ"</string>
+ <string name="whichEditApplication" msgid="6191568491456092812">"Измените помоћу"</string>
+ <string name="whichEditApplicationNamed" msgid="8096494987978521514">"Измените помоћу апликације %1$s"</string>
+ <string name="whichEditApplicationLabel" msgid="1463288652070140285">"Измени"</string>
+ <string name="whichSendApplication" msgid="4143847974460792029">"Делите"</string>
+ <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Делите помоћу апликације %1$s"</string>
+ <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Дели"</string>
+ <string name="whichSendToApplication" msgid="77101541959464018">"Пошаљите помоћу:"</string>
+ <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Пошаљите помоћу: %1$s"</string>
+ <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Пошаљи"</string>
+ <string name="whichHomeApplication" msgid="8276350727038396616">"Изаберите апликацију за почетну страницу"</string>
+ <string name="whichHomeApplicationNamed" msgid="5855990024847433794">"Користите %1$s за почетну"</string>
+ <string name="whichHomeApplicationLabel" msgid="8907334282202933959">"Снимите слику"</string>
+ <string name="whichImageCaptureApplication" msgid="2737413019463215284">"Снимите слику помоћу апликације"</string>
+ <string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Снимите слику помоћу апликације %1$s"</string>
+ <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Снимите слику"</string>
+ <string name="alwaysUse" msgid="3153558199076112903">"Подразумевано користи за ову радњу."</string>
+ <string name="use_a_different_app" msgid="4987790276170972776">"Користите другу апликацију"</string>
+ <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Обришите подразумевано подешавање у менију Подешавања система > Апликације > Преузето."</string>
+ <string name="chooseActivity" msgid="8563390197659779956">"Изаберите радњу"</string>
+ <string name="chooseUsbActivity" msgid="2096269989990986612">"Избор апликације за USB уређај"</string>
+ <string name="noApplications" msgid="1186909265235544019">"Ниједна апликација не може да обавља ову радњу."</string>
+ <string name="aerr_application" msgid="4090916809370389109">"Апликација <xliff:g id="APPLICATION">%1$s</xliff:g> је заустављена"</string>
+ <string name="aerr_process" msgid="4268018696970966407">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> је заустављен"</string>
+ <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> се стално зауставља"</string>
+ <string name="aerr_process_repeated" msgid="1153152413537954974">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> се стално зауставља"</string>
+ <string name="aerr_restart" msgid="2789618625210505419">"Поново отвори апликацију"</string>
+ <string name="aerr_report" msgid="3095644466849299308">"Пошаљите повратне информације"</string>
+ <string name="aerr_close" msgid="3398336821267021852">"Затвори"</string>
+ <string name="aerr_mute" msgid="2304972923480211376">"Игнориши док се уређај не покрене поново"</string>
+ <string name="aerr_wait" msgid="3198677780474548217">"Чекај"</string>
+ <string name="aerr_close_app" msgid="8318883106083050970">"Затвори апликацију"</string>
<string name="anr_title" msgid="7290329487067300120"></string>
- <string name="anr_activity_application" msgid="8121716632960340680">"<xliff:g id="APPLICATION">%2$s</xliff:g> ne reaguje"</string>
- <string name="anr_activity_process" msgid="3477362583767128667">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ne reaguje"</string>
- <string name="anr_application_process" msgid="4978772139461676184">"<xliff:g id="APPLICATION">%1$s</xliff:g> ne reaguje"</string>
- <string name="anr_process" msgid="1664277165911816067">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> ne reaguje"</string>
- <string name="force_close" msgid="9035203496368973803">"Potvrdi"</string>
- <string name="report" msgid="2149194372340349521">"Prijavi"</string>
- <string name="wait" msgid="7765985809494033348">"Sačekaj"</string>
- <string name="webpage_unresponsive" msgid="7850879412195273433">"Stranica je prestala da se odaziva.\n\n Da li želite da je zatvorite?"</string>
- <string name="launch_warning_title" msgid="6725456009564953595">"Aplikacija je preusmerena"</string>
- <string name="launch_warning_replace" msgid="3073392976283203402">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je sada pokrenuta."</string>
- <string name="launch_warning_original" msgid="3332206576800169626">"Prvobitno je pokrenuta aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Razmera"</string>
- <string name="screen_compat_mode_show" msgid="5080361367584709857">"Uvek prikazuj"</string>
- <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Ponovo omogućite u meniju Sistemska podešavanja > Aplikacije > Preuzeto."</string>
- <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava trenutno podešavanje veličine prikaza i može da se ponaša neočekivano."</string>
- <string name="unsupported_display_size_show" msgid="980129850974919375">"Uvek prikazuj"</string>
- <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je napravljena za nekompatibilnu verziju Android OS-a i može da se ponaša na neočekivan način. Možda je dostupna ažurirana verzija aplikacije."</string>
- <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Uvek prikaži"</string>
- <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Potraži ažuriranje"</string>
- <string name="smv_application" msgid="3775183542777792638">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) je prekršila samonametnute StrictMode smernice."</string>
- <string name="smv_process" msgid="1398801497130695446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> je prekršio samonametnute StrictMode smernice."</string>
- <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Telefon se ažurira…"</string>
- <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Tablet se ažurira…"</string>
- <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Uređaj se ažurira…"</string>
- <string name="android_start_title" product="default" msgid="4036708252778757652">"Telefon se pokreće…"</string>
- <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android se pokreće…"</string>
- <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet se pokreće…"</string>
- <string name="android_start_title" product="device" msgid="6967413819673299309">"Uređaj se pokreće…"</string>
- <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Memorija se optimizuje."</string>
- <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Ažuriranje sistema se dovršava…"</string>
- <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> se nadograđuje…"</string>
- <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimizovanje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
- <string name="android_preparing_apk" msgid="589736917792300956">"Priprema se <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
- <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
- <string name="android_upgrading_complete" msgid="409800058018374746">"Završavanje pokretanja."</string>
- <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Pritisnuli ste dugme za uključivanje – time obično isključujete ekran.\n\nProbajte lagano da dodirnete dok podešavate otisak prsta."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Završite podešavanje isključivanjem ekrana"</string>
- <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Isključi"</string>
- <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Nastavljate verifikaciju otiska prsta?"</string>
- <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Pritisnuli ste dugme za uključivanje – time obično isključujete ekran.\n\nProbajte lagano da dodirnete da biste verifikovali otisak prsta."</string>
- <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Isključi ekran"</string>
- <string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"Nastavi"</string>
- <string name="heavy_weight_notification" msgid="8382784283600329576">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je pokrenuta"</string>
- <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Dodirnite da biste se vratili u igru"</string>
- <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Odaberite igru"</string>
- <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"Da bi performanse bile bolje, može da bude otvorena samo jedna od ovih igara."</string>
- <string name="old_app_action" msgid="725331621042848590">"Nazad na <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
- <string name="new_app_action" msgid="547772182913269801">"Otvori <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
- <string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> će se zatvoriti bez čuvanja"</string>
- <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> premašuje ograničenje memorije"</string>
- <string name="dump_heap_ready_notification" msgid="2302452262927390268">"Snimak dinamičkog dela memorije za proces <xliff:g id="PROC">%1$s</xliff:g> je spreman"</string>
- <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Snimak dinamičkog dela memorije je napravljen. Dodirnite za deljenje."</string>
- <string name="dump_heap_title" msgid="4367128917229233901">"Želite li da delite snimak dinamičkog dela memorije?"</string>
- <string name="dump_heap_text" msgid="1692649033835719336">"Proces <xliff:g id="PROC">%1$s</xliff:g> je premašio ograničenje memorije od <xliff:g id="SIZE">%2$s</xliff:g>. Snimak dinamičkog dela memorije je dostupan i možete da ga delite sa programerom. Budite oprezni: ovaj snimak dinamičkog dela memorije može da sadrži neke lične podatke kojima aplikacija može da pristupa."</string>
- <string name="dump_heap_system_text" msgid="6805155514925350849">"Proces <xliff:g id="PROC">%1$s</xliff:g> je premašio ograničenje memorije od <xliff:g id="SIZE">%2$s</xliff:g>. Snimak dinamičkog dela memorije je dostupan i možete da ga delite. Budite oprezni: ovaj snimak dinamičkog dela memorije može da sadrži osetljive lične podatke kojima proces može da pristupa, što može da obuhvata tekst koji ste unosili."</string>
- <string name="dump_heap_ready_text" msgid="5849618132123045516">"Snimak dinamičkog dela memorije za proces <xliff:g id="PROC">%1$s</xliff:g> je dostupan i možete da ga delite. Budite oprezni: ovaj snimak dinamičkog dela memorije može da sadrži osetljive lične podatke kojima proces može da pristupa, što može da obuhvata tekst koji ste unosili."</string>
- <string name="sendText" msgid="493003724401350724">"Izaberite radnju za tekst"</string>
- <string name="volume_ringtone" msgid="134784084629229029">"Jačina zvuka zvona"</string>
- <string name="volume_music" msgid="7727274216734955095">"Jačina zvuka medija"</string>
- <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Igranje preko Bluetooth-a"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Podešen je nečujni zvuk zvona"</string>
- <string name="volume_call" msgid="7625321655265747433">"Jačina zvuka dolaznog poziva"</string>
- <string name="volume_bluetooth_call" msgid="2930204618610115061">"Jačina zvuka dolazećeg poziva preko Bluetooth-a"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"Jačina zvuka alarma"</string>
- <string name="volume_notification" msgid="6864412249031660057">"Jačina zvuka za obaveštenja"</string>
- <string name="volume_unknown" msgid="4041914008166576293">"Jačina zvuka"</string>
- <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Jačina zvuka Bluetooth uređaja"</string>
- <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Jačina melodije zvona"</string>
- <string name="volume_icon_description_incall" msgid="4491255105381227919">"Jačina zvuka poziva"</string>
- <string name="volume_icon_description_media" msgid="4997633254078171233">"Jačina zvuka medija"</string>
- <string name="volume_icon_description_notification" msgid="579091344110747279">"Jačina zvuka obaveštenja"</string>
- <string name="ringtone_default" msgid="9118299121288174597">"Podrazumevani zvuk zvona"</string>
- <string name="ringtone_default_with_actual" msgid="2709686194556159773">"Podrazumevano (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"Bez zvuka"</string>
- <string name="ringtone_picker_title" msgid="667342618626068253">"Zvukovi zvona"</string>
- <string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Zvuci alarma"</string>
- <string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Zvuci obaveštenja"</string>
- <string name="ringtone_unknown" msgid="5059495249862816475">"Nepoznato"</string>
- <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavljivanje na WiFi mrežu"</string>
- <string name="network_available_sign_in" msgid="1520342291829283114">"Prijavite se na mrežu"</string>
+ <string name="anr_activity_application" msgid="8121716632960340680">"<xliff:g id="APPLICATION">%2$s</xliff:g> не реагује"</string>
+ <string name="anr_activity_process" msgid="3477362583767128667">"<xliff:g id="ACTIVITY">%1$s</xliff:g> не реагује"</string>
+ <string name="anr_application_process" msgid="4978772139461676184">"<xliff:g id="APPLICATION">%1$s</xliff:g> не реагује"</string>
+ <string name="anr_process" msgid="1664277165911816067">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> не реагује"</string>
+ <string name="force_close" msgid="9035203496368973803">"Потврди"</string>
+ <string name="report" msgid="2149194372340349521">"Пријави"</string>
+ <string name="wait" msgid="7765985809494033348">"Сачекај"</string>
+ <string name="webpage_unresponsive" msgid="7850879412195273433">"Страница је престала да се одазива.\n\n Да ли желите да је затворите?"</string>
+ <string name="launch_warning_title" msgid="6725456009564953595">"Апликација је преусмерена"</string>
+ <string name="launch_warning_replace" msgid="3073392976283203402">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је сада покренута."</string>
+ <string name="launch_warning_original" msgid="3332206576800169626">"Првобитно је покренута апликација <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Размера"</string>
+ <string name="screen_compat_mode_show" msgid="5080361367584709857">"Увек приказуј"</string>
+ <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Поново омогућите у менију Системска подешавања > Апликације > Преузето."</string>
+ <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> не подржава тренутно подешавање величине приказа и може да се понаша неочекивано."</string>
+ <string name="unsupported_display_size_show" msgid="980129850974919375">"Увек приказуј"</string>
+ <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је направљена за некомпатибилну верзију Android ОС-а и може да се понаша на неочекиван начин. Можда је доступна ажурирана верзија апликације."</string>
+ <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Увек прикажи"</string>
+ <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Потражи ажурирање"</string>
+ <string name="smv_application" msgid="3775183542777792638">"Апликација <xliff:g id="APPLICATION">%1$s</xliff:g> (процес <xliff:g id="PROCESS">%2$s</xliff:g>) је прекршила самонаметнуте StrictMode смернице."</string>
+ <string name="smv_process" msgid="1398801497130695446">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> је прекршио самонаметнуте StrictMode смернице."</string>
+ <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Телефон се ажурира…"</string>
+ <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Таблет се ажурира…"</string>
+ <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Уређај се ажурира…"</string>
+ <string name="android_start_title" product="default" msgid="4036708252778757652">"Телефон се покреће…"</string>
+ <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android се покреће…"</string>
+ <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Таблет се покреће…"</string>
+ <string name="android_start_title" product="device" msgid="6967413819673299309">"Уређај се покреће…"</string>
+ <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Меморија се оптимизује."</string>
+ <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Ажурирање система се довршава…"</string>
+ <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> се надограђује…"</string>
+ <string name="android_upgrading_apk" msgid="1339564803894466737">"Оптимизовање апликације <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="android_preparing_apk" msgid="589736917792300956">"Припрема се <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
+ <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Покретање апликација."</string>
+ <string name="android_upgrading_complete" msgid="409800058018374746">"Завршавање покретања."</string>
+ <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Притиснули сте дугме за укључивање – тиме обично искључујете екран.\n\nПробајте лагано да додирнете док подешавате отисак прста."</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Завршите подешавање искључивањем екрана"</string>
+ <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Искључи"</string>
+ <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Настављате верификацију отиска прста?"</string>
+ <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Притиснули сте дугме за укључивање – тиме обично искључујете екран.\n\nПробајте лагано да додирнете да бисте верификовали отисак прста."</string>
+ <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Искључи екран"</string>
+ <string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"Настави"</string>
+ <string name="heavy_weight_notification" msgid="8382784283600329576">"Апликација <xliff:g id="APP">%1$s</xliff:g> је покренута"</string>
+ <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Додирните да бисте се вратили у игру"</string>
+ <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Одаберите игру"</string>
+ <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"Да би перформансе биле боље, може да буде отворена само једна од ових игара."</string>
+ <string name="old_app_action" msgid="725331621042848590">"Назад на <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+ <string name="new_app_action" msgid="547772182913269801">"Отвори <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
+ <string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> ће се затворити без чувања"</string>
+ <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> премашује ограничење меморије"</string>
+ <string name="dump_heap_ready_notification" msgid="2302452262927390268">"Снимак динамичког дела меморије за процес <xliff:g id="PROC">%1$s</xliff:g> је спреман"</string>
+ <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Снимак динамичког дела меморије је направљен. Додирните за дељење."</string>
+ <string name="dump_heap_title" msgid="4367128917229233901">"Желите ли да делите снимак динамичког дела меморије?"</string>
+ <string name="dump_heap_text" msgid="1692649033835719336">"Процес <xliff:g id="PROC">%1$s</xliff:g> је премашио ограничење меморије од <xliff:g id="SIZE">%2$s</xliff:g>. Снимак динамичког дела меморије је доступан и можете да га делите са програмером. Будите опрезни: овај снимак динамичког дела меморије може да садржи неке личне податке којима апликација може да приступа."</string>
+ <string name="dump_heap_system_text" msgid="6805155514925350849">"Процес <xliff:g id="PROC">%1$s</xliff:g> је премашио ограничење меморије од <xliff:g id="SIZE">%2$s</xliff:g>. Снимак динамичког дела меморије је доступан и можете да га делите. Будите опрезни: овај снимак динамичког дела меморије може да садржи осетљиве личне податке којима процес може да приступа, што може да обухвата текст који сте уносили."</string>
+ <string name="dump_heap_ready_text" msgid="5849618132123045516">"Снимак динамичког дела меморије за процес <xliff:g id="PROC">%1$s</xliff:g> је доступан и можете да га делите. Будите опрезни: овај снимак динамичког дела меморије може да садржи осетљиве личне податке којима процес може да приступа, што може да обухвата текст који сте уносили."</string>
+ <string name="sendText" msgid="493003724401350724">"Изаберите радњу за текст"</string>
+ <string name="volume_ringtone" msgid="134784084629229029">"Јачина звука звона"</string>
+ <string name="volume_music" msgid="7727274216734955095">"Јачина звука медија"</string>
+ <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Играње преко Bluetooth-а"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Подешен је нечујни звук звона"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Јачина звука долазног позива"</string>
+ <string name="volume_bluetooth_call" msgid="2930204618610115061">"Јачина звука долазећег позива преко Bluetooth-а"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"Јачина звука аларма"</string>
+ <string name="volume_notification" msgid="6864412249031660057">"Јачина звука за обавештења"</string>
+ <string name="volume_unknown" msgid="4041914008166576293">"Јачина звука"</string>
+ <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Јачина звука Bluetooth уређаја"</string>
+ <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Јачина мелодије звона"</string>
+ <string name="volume_icon_description_incall" msgid="4491255105381227919">"Јачина звука позива"</string>
+ <string name="volume_icon_description_media" msgid="4997633254078171233">"Јачина звука медија"</string>
+ <string name="volume_icon_description_notification" msgid="579091344110747279">"Јачина звука обавештења"</string>
+ <string name="ringtone_default" msgid="9118299121288174597">"Подразумевани звук звона"</string>
+ <string name="ringtone_default_with_actual" msgid="2709686194556159773">"Подразумевано (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"Без звука"</string>
+ <string name="ringtone_picker_title" msgid="667342618626068253">"Звукови звона"</string>
+ <string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Звуци аларма"</string>
+ <string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Звуци обавештења"</string>
+ <string name="ringtone_unknown" msgid="5059495249862816475">"Непознато"</string>
+ <string name="wifi_available_sign_in" msgid="381054692557675237">"Пријављивање на WiFi мрежу"</string>
+ <string name="network_available_sign_in" msgid="1520342291829283114">"Пријавите се на мрежу"</string>
<!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
<skip />
- <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
- <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dodirnite za opcije"</string>
- <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilna mreža nema pristup internetu"</string>
- <string name="other_networks_no_internet" msgid="6698711684200067033">"Mreža nema pristup internetu"</string>
- <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Pristup privatnom DNS serveru nije uspeo"</string>
- <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu vezu"</string>
- <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dodirnite da biste se ipak povezali"</string>
- <string name="network_switch_metered" msgid="1531869544142283384">"Prešli ste na tip mreže <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="1358296010128405906">"Uređaj koristi tip mreže <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kada tip mreže <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu. Možda će se naplaćivati troškovi."</string>
- <string name="network_switch_metered_toast" msgid="501662047275723743">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+ <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема приступ интернету"</string>
+ <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Додирните за опције"</string>
+ <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилна мрежа нема приступ интернету"</string>
+ <string name="other_networks_no_internet" msgid="6698711684200067033">"Мрежа нема приступ интернету"</string>
+ <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Приступ приватном DNS серверу није успео"</string>
+ <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничену везу"</string>
+ <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Додирните да бисте се ипак повезали"</string>
+ <string name="network_switch_metered" msgid="1531869544142283384">"Прешли сте на тип мреже <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+ <string name="network_switch_metered_detail" msgid="1358296010128405906">"Уређај користи тип мреже <xliff:g id="NEW_NETWORK">%1$s</xliff:g> када тип мреже <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема приступ интернету. Можда ће се наплаћивати трошкови."</string>
+ <string name="network_switch_metered_toast" msgid="501662047275723743">"Прешли сте са типа мреже <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на тип мреже <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
<string-array name="network_switch_type_name">
- <item msgid="2255670471736226365">"mobilni podaci"</item>
+ <item msgid="2255670471736226365">"мобилни подаци"</item>
<item msgid="5520925862115353992">"WiFi"</item>
<item msgid="1055487873974272842">"Bluetooth"</item>
- <item msgid="1616528372438698248">"Eternet"</item>
+ <item msgid="1616528372438698248">"Етернет"</item>
<item msgid="9177085807664964627">"VPN"</item>
</string-array>
- <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznat tip mreže"</string>
- <string name="accept" msgid="5447154347815825107">"Prihvati"</string>
- <string name="decline" msgid="6490507610282145874">"Odbij"</string>
- <string name="select_character" msgid="3352797107930786979">"Umetanje znaka"</string>
- <string name="sms_control_title" msgid="4748684259903148341">"Slanje SMS poruka"</string>
- <string name="sms_control_message" msgid="6574313876316388239">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> šalje veliki broj SMS poruka. Želite li da dozvolite ovoj aplikaciji da nastavi sa slanjem poruka?"</string>
- <string name="sms_control_yes" msgid="4858845109269524622">"Dozvoli"</string>
- <string name="sms_control_no" msgid="4845717880040355570">"Odbij"</string>
- <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> želi da pošalje poruku na adresu <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
- <string name="sms_short_code_details" msgid="2723725738333388351">"Ovo "<b>"može da prouzrokuje troškove"</b>" na računu za mobilni uređaj."</string>
- <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"Ovo će prouzrokovati troškove na računu za mobilni uređaj."</b></string>
- <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"Pošalji"</string>
- <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Otkaži"</string>
- <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Zapamti moj izbor"</string>
- <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Ovo možete da promenite kasnije u Podešavanja > Aplikacije"</string>
- <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Uvek dozvoli"</string>
- <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Nikada ne dozvoli"</string>
- <string name="sim_removed_title" msgid="5387212933992546283">"SIM kartica je uklonjena"</string>
- <string name="sim_removed_message" msgid="9051174064474904617">"Mobilna mreža neće biti dostupna dok ne pokrenete sistem ponovo uz umetanje važeće SIM kartice."</string>
- <string name="sim_done_button" msgid="6464250841528410598">"Gotovo"</string>
- <string name="sim_added_title" msgid="7930779986759414595">"SIM kartica je dodata"</string>
- <string name="sim_added_message" msgid="6602906609509958680">"Restartujte uređaj da biste mogli da pristupite mobilnoj mreži."</string>
- <string name="sim_restart_button" msgid="8481803851341190038">"Restartuj"</string>
- <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Aktivirajte mobilnu uslugu"</string>
- <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Preuzmite aplikaciju mobilnog operatera da biste aktivirali novi SIM"</string>
- <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Preuzmite aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> da biste aktivirali novu SIM karticu"</string>
- <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Preuzmite aplikaciju"</string>
- <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nova SIM kartica je umetnuta"</string>
- <string name="carrier_app_notification_text" msgid="6567057546341958637">"Dodirnite za podešavanje"</string>
- <string name="time_picker_dialog_title" msgid="9053376764985220821">"Podesite vreme"</string>
- <string name="date_picker_dialog_title" msgid="5030520449243071926">"Podešavanje datuma"</string>
- <string name="date_time_set" msgid="4603445265164486816">"Podesi"</string>
- <string name="date_time_done" msgid="8363155889402873463">"Gotovo"</string>
- <string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"NOVO: "</font></string>
- <string name="perms_description_app" msgid="2747752389870161996">"Omogućava <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <string name="no_permissions" msgid="5729199278862516390">"Nije potrebna nijedna dozvola"</string>
- <string name="perm_costs_money" msgid="749054595022779685">"ovo će vam možda biti naplaćeno"</string>
- <string name="dlg_ok" msgid="5103447663504839312">"Potvrdi"</string>
- <string name="usb_charging_notification_title" msgid="1674124518282666955">"Ovaj uređaj se puni preko USB-a"</string>
- <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Povezani uređaj se puni preko USB-a"</string>
- <string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB prenos datoteka je uključen"</string>
- <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Režim PTP preko USB-a je uključen"</string>
- <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB privezivanje je uključeno"</string>
- <string name="usb_midi_notification_title" msgid="7404506788950595557">"Režim MIDI preko USB-a je uključen"</string>
- <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB dodatak je povezan"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"Dodirnite za još opcija."</string>
- <string name="usb_power_notification_message" msgid="7284765627437897702">"Povezani uređaj se puni. Dodirnite za još opcija."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Otkrivena je analogna dodatna oprema za audio sadržaj"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Priključeni uređaj nije kompatibilan sa ovim telefonom. Dodirnite da biste saznali više."</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"Povezano je otklanjanje grešaka sa USB-a"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Dodirnite da biste ga isključili"</string>
- <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Izaberite da biste onemogućili otklanjanja grešaka sa USB-a."</string>
- <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Bežično otklanjanje grešaka je povezano"</string>
- <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Dodirnite da biste isključili bežično otklanjanje grešaka"</string>
- <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Izaberite da biste onemogućili bežično otklanjanje grešaka."</string>
- <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen je režim probnog korišćenja"</string>
- <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Obavite resetovanje na fabrička podešavanja da biste onemogućili režim probnog korišćenja."</string>
- <string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola je omogućena"</string>
- <string name="console_running_notification_message" msgid="7892751888125174039">"Performanse su smanjene. Da biste onemogući konzolu, proverite pokretački program."</string>
- <string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentalni MTE je omogućen"</string>
- <string name="mte_override_notification_message" msgid="2441170442725738942">"Ovo može da utiče na performanse i stabilnost. Restartujte da biste onemogućili. Ako je omogućeno pomoću arm64.memtag.bootctl, prvo podesite na Ništa."</string>
- <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"Tečnost ili nečistoća u USB portu"</string>
- <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB port je automatski isključen. Dodirnite da biste saznali više."</string>
- <string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"Korišćenje USB porta je dozvoljeno"</string>
- <string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"Telefon više ne otkriva tečnost ili nečistoću."</string>
- <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Izveštaj o grešci se generiše…"</string>
- <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Želite li da podelite izveštaj o grešci?"</string>
- <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Deli se izveštaj o grešci…"</string>
- <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema u vezi sa ovim uređajem. Aplikacije i podaci mogu da se dele."</string>
- <string name="share_remote_bugreport_action" msgid="7630880678785123682">"DELI"</string>
- <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODBIJ"</string>
- <string name="select_input_method" msgid="3971267998568587025">"Izbor metoda unosa"</string>
- <string name="show_ime" msgid="6406112007347443383">"Zadržava se na ekranu dok je fizička tastatura aktivna"</string>
- <string name="hardware" msgid="1800597768237606953">"Prikaži virtuelnu tastaturu"</string>
- <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Konfigurišite fizičku tastaturu"</string>
- <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite da biste izabrali jezik i raspored"</string>
+ <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"непознат тип мреже"</string>
+ <string name="accept" msgid="5447154347815825107">"Прихвати"</string>
+ <string name="decline" msgid="6490507610282145874">"Одбиј"</string>
+ <string name="select_character" msgid="3352797107930786979">"Уметање знака"</string>
+ <string name="sms_control_title" msgid="4748684259903148341">"Слање SMS порука"</string>
+ <string name="sms_control_message" msgid="6574313876316388239">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> шаље велики број SMS порука. Желите ли да дозволите овој апликацији да настави са слањем порука?"</string>
+ <string name="sms_control_yes" msgid="4858845109269524622">"Дозволи"</string>
+ <string name="sms_control_no" msgid="4845717880040355570">"Одбиј"</string>
+ <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> жели да пошаље поруку на адресу <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
+ <string name="sms_short_code_details" msgid="2723725738333388351">"Ово "<b>"може да проузрокује трошкове"</b>" на рачуну за мобилни уређај."</string>
+ <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"Ово ће проузроковати трошкове на рачуну за мобилни уређај."</b></string>
+ <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"Пошаљи"</string>
+ <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Откажи"</string>
+ <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Запамти мој избор"</string>
+ <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Ово можете да промените касније у Подешавања > Апликације"</string>
+ <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Увек дозволи"</string>
+ <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Никада не дозволи"</string>
+ <string name="sim_removed_title" msgid="5387212933992546283">"SIM картица је уклоњена"</string>
+ <string name="sim_removed_message" msgid="9051174064474904617">"Мобилна мрежа неће бити доступна док не покренете систем поново уз уметање важеће SIM картице."</string>
+ <string name="sim_done_button" msgid="6464250841528410598">"Готово"</string>
+ <string name="sim_added_title" msgid="7930779986759414595">"SIM картица је додата"</string>
+ <string name="sim_added_message" msgid="6602906609509958680">"Рестартујте уређај да бисте могли да приступите мобилној мрежи."</string>
+ <string name="sim_restart_button" msgid="8481803851341190038">"Рестартуј"</string>
+ <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Активирајте мобилну услугу"</string>
+ <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Преузмите апликацију мобилног оператера да бисте активирали нови SIM"</string>
+ <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Преузмите апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> да бисте активирали нову SIM картицу"</string>
+ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Преузмите апликацију"</string>
+ <string name="carrier_app_notification_title" msgid="5815477368072060250">"Нова SIM картица је уметнута"</string>
+ <string name="carrier_app_notification_text" msgid="6567057546341958637">"Додирните за подешавање"</string>
+ <string name="time_picker_dialog_title" msgid="9053376764985220821">"Подесите време"</string>
+ <string name="date_picker_dialog_title" msgid="5030520449243071926">"Подешавање датума"</string>
+ <string name="date_time_set" msgid="4603445265164486816">"Подеси"</string>
+ <string name="date_time_done" msgid="8363155889402873463">"Готово"</string>
+ <string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"НОВО: "</font></string>
+ <string name="perms_description_app" msgid="2747752389870161996">"Омогућава <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="no_permissions" msgid="5729199278862516390">"Није потребна ниједна дозвола"</string>
+ <string name="perm_costs_money" msgid="749054595022779685">"ово ће вам можда бити наплаћено"</string>
+ <string name="dlg_ok" msgid="5103447663504839312">"Потврди"</string>
+ <string name="usb_charging_notification_title" msgid="1674124518282666955">"Овај уређај се пуни преко USB-а"</string>
+ <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Повезани уређај се пуни преко USB-а"</string>
+ <string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB пренос датотека је укључен"</string>
+ <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Режим PTP преко USB-а је укључен"</string>
+ <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB привезивање је укључено"</string>
+ <string name="usb_midi_notification_title" msgid="7404506788950595557">"Режим MIDI преко USB-а је укључен"</string>
+ <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB додатак је повезан"</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"Додирните за још опција."</string>
+ <string name="usb_power_notification_message" msgid="7284765627437897702">"Повезани уређај се пуни. Додирните за још опција."</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Откривена је аналогна додатна опрема за аудио садржај"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Прикључени уређај није компатибилан са овим телефоном. Додирните да бисте сазнали више."</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"Повезано је отклањање грешака са USB-а"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Додирните да бисте га искључили"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
+ <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Бежично отклањање грешака је повезано"</string>
+ <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Додирните да бисте искључили бежично отклањање грешака"</string>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изаберите да бисте онемогућили бежично отклањање грешака."</string>
+ <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Омогућен је режим пробног коришћења"</string>
+ <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Обавите ресетовање на фабричка подешавања да бисте онемогућили режим пробног коришћења."</string>
+ <string name="console_running_notification_title" msgid="6087888939261635904">"Серијска конзола је омогућена"</string>
+ <string name="console_running_notification_message" msgid="7892751888125174039">"Перформансе су смањене. Да бисте онемогући конзолу, проверите покретачки програм."</string>
+ <string name="mte_override_notification_title" msgid="4731115381962792944">"Експериментални MTE је омогућен"</string>
+ <string name="mte_override_notification_message" msgid="2441170442725738942">"Ово може да утиче на перформансе и стабилност. Рестартујте да бисте онемогућили. Ако је омогућено помоћу arm64.memtag.bootctl, прво подесите на Ништа."</string>
+ <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"Течност или нечистоћа у USB порту"</string>
+ <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB порт је аутоматски искључен. Додирните да бисте сазнали више."</string>
+ <string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"Коришћење USB порта је дозвољено"</string>
+ <string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"Телефон више не открива течност или нечистоћу."</string>
+ <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Извештај о грешци се генерише…"</string>
+ <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Желите ли да поделите извештај о грешци?"</string>
+ <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Дели се извештај о грешци…"</string>
+ <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Администратор је затражио извештај о грешци ради лакшег решавања проблема у вези са овим уређајем. Апликације и подаци могу да се деле."</string>
+ <string name="share_remote_bugreport_action" msgid="7630880678785123682">"ДЕЛИ"</string>
+ <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ОДБИЈ"</string>
+ <string name="select_input_method" msgid="3971267998568587025">"Избор метода уноса"</string>
+ <string name="show_ime" msgid="6406112007347443383">"Задржава се на екрану док је физичка тастатура активна"</string>
+ <string name="hardware" msgid="1800597768237606953">"Прикажи виртуелну тастатуру"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Конфигуришите физичку тастатуру"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Додирните да бисте изабрали језик и распоред"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Prikaz preko drugih aplikacija"</string>
- <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"Aplikacija <xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplikacija"</string>
- <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih apl."</string>
- <string name="alert_windows_notification_message" msgid="6538171456970725333">"Ako ne želite ovu funkciju za <xliff:g id="NAME">%s</xliff:g>, dodirnite da biste otvorili podešavanja i isključili je."</string>
- <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Isključi"</string>
- <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Proverava se <xliff:g id="NAME">%s</xliff:g>…"</string>
- <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Pregleda se aktuelni sadržaj"</string>
- <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analizira se memorijski prostor za medije"</string>
- <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Novi/a <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
- <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Dodirnite da biste podesili"</string>
- <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Izaberite da biste podesili"</string>
- <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Možda morate da reformatirate uređaj. Dodirnite da biste izbacili."</string>
- <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"Za čuvanje slika, video snimaka, muzike i drugog sadržaja"</string>
- <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Pregledajte medijske fajlove"</string>
- <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem sa: <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
- <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Dodirnite da biste ispravili"</string>
- <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"Medij <xliff:g id="NAME">%s</xliff:g> je oštećen. Izaberite da ga popravite."</string>
- <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"Možda morate da reformatirate uređaj. Dodirnite da biste izbacili."</string>
- <string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"Otkriveno: <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string>
- <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"Dodirnite da biste podesili."</string>
- <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Izaberite da biste podesili uređaj <xliff:g id="NAME">%s</xliff:g> u podržanom formatu."</string>
- <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Možda morate da reformatirate uređaj"</string>
- <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Uređaj <xliff:g id="NAME">%s</xliff:g> je neočekivano uklonjen"</string>
- <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Izbacite medijum pre nego što ga uklonite da ne biste izgubili sadržaj"</string>
- <string name="ext_media_nomedia_notification_title" msgid="742671636376975890">"<xliff:g id="NAME">%s</xliff:g> je uklonjen/a"</string>
- <string name="ext_media_nomedia_notification_message" msgid="2832724384636625852">"Neke funkcije možda neće ispravno raditi. Umetnite nov memorijski uređaj."</string>
- <string name="ext_media_unmounting_notification_title" msgid="4147986383917892162">"Izbacuje se <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="ext_media_unmounting_notification_message" msgid="5717036261538754203">"Ne uklanjajte"</string>
- <string name="ext_media_init_action" msgid="2312974060585056709">"Aktiviraj"</string>
- <string name="ext_media_unmount_action" msgid="966992232088442745">"Izbaci"</string>
- <string name="ext_media_browse_action" msgid="344865351947079139">"Istraži"</string>
- <string name="ext_media_seamless_action" msgid="8837030226009268080">"Promenite izlaz"</string>
- <string name="ext_media_missing_title" msgid="3209472091220515046">"<xliff:g id="NAME">%s</xliff:g> nedostaje"</string>
- <string name="ext_media_missing_message" msgid="4408988706227922909">"Ponovo umetnite uređaj"</string>
- <string name="ext_media_move_specific_title" msgid="8492118544775964250">"Prenosi se <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="ext_media_move_title" msgid="2682741525619033637">"Podaci se prenose"</string>
- <string name="ext_media_move_success_title" msgid="4901763082647316767">"Prenos sadržaja je gotov"</string>
- <string name="ext_media_move_success_message" msgid="9159542002276982979">"Sadržaj je premešen na: <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="ext_media_move_failure_title" msgid="3184577479181333665">"Premeštanje sadržaja nije uspelo"</string>
- <string name="ext_media_move_failure_message" msgid="4197306718121869335">"Probajte da ponovo premestite sadržaj"</string>
- <string name="ext_media_status_removed" msgid="241223931135751691">"Uklonjen je"</string>
- <string name="ext_media_status_unmounted" msgid="8145812017295835941">"Izbačen je"</string>
- <string name="ext_media_status_checking" msgid="159013362442090347">"Proverava se..."</string>
- <string name="ext_media_status_mounted" msgid="3459448555811203459">"Spreman je"</string>
- <string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"Samo za čitanje"</string>
- <string name="ext_media_status_bad_removal" msgid="508448566481406245">"Uklonjen je na nebezbedan način"</string>
- <string name="ext_media_status_unmountable" msgid="7043574843541087748">"Oštećen je"</string>
- <string name="ext_media_status_unsupported" msgid="5460509911660539317">"Nije podržan"</string>
- <string name="ext_media_status_ejecting" msgid="7532403368044013797">"Izbacuje se..."</string>
- <string name="ext_media_status_formatting" msgid="774148701503179906">"Formatira se..."</string>
- <string name="ext_media_status_missing" msgid="6520746443048867314">"Nije umetnut"</string>
- <string name="activity_list_empty" msgid="4219430010716034252">"Nije pronađena nijedna podudarna aktivnost."</string>
- <string name="permlab_route_media_output" msgid="8048124531439513118">"usmeravanje izlaza medija"</string>
- <string name="permdesc_route_media_output" msgid="1759683269387729675">"Dozvoljava aplikaciji da usmerava izlaz medija na druge spoljne uređaje."</string>
- <string name="permlab_readInstallSessions" msgid="7279049337895583621">"čitanje sesija instaliranja"</string>
- <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Dozvoljava aplikaciji da čita sesije instaliranja. To joj dozvoljava da vidi detalje o aktivnim instalacijama paketa."</string>
- <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"zahtevanje paketa za instaliranje"</string>
- <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Omogućava da aplikacija zahteva instalaciju paketa."</string>
- <string name="permlab_requestDeletePackages" msgid="2541172829260106795">"zahtevanje brisanja paketa"</string>
- <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Omogućava da aplikacija zahteva brisanje paketa."</string>
- <string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"traženje dozvole za ignorisanje optimizacija baterije"</string>
- <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Dozvoljava aplikaciji da traži dozvolu za ignorisanje optimizacija baterije za tu aplikaciju."</string>
- <string name="permlab_queryAllPackages" msgid="2928450604653281650">"slanje upita za sve pakete"</string>
- <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Dozvoljava aplikaciji da vidi sve instalirane pakete."</string>
- <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dodirnite dvaput za kontrolu zumiranja"</string>
- <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nije moguće dodati vidžet."</string>
- <string name="ime_action_go" msgid="5536744546326495436">"Idi"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"Pretraži"</string>
- <string name="ime_action_send" msgid="8456843745664334138">"Pošalji"</string>
- <string name="ime_action_next" msgid="4169702997635728543">"Dalje"</string>
- <string name="ime_action_done" msgid="6299921014822891569">"Gotovo"</string>
- <string name="ime_action_previous" msgid="6548799326860401611">"Prethodno"</string>
- <string name="ime_action_default" msgid="8265027027659800121">"Izvrši"</string>
- <string name="dial_number_using" msgid="6060769078933953531">"Biraj broj\nkoristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
- <string name="create_contact_using" msgid="6200708808003692594">"Napravite kontakt\nkoristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
- <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Sledeće aplikacije zahtevaju dozvolu za pristup nalogu, kako sada, tako i ubuduće."</string>
- <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Želite da odobrite ovaj zahtev?"</string>
- <string name="grant_permissions_header_text" msgid="3420736827804657201">"Zahtev za pristup"</string>
- <string name="allow" msgid="6195617008611933762">"Dozvoli"</string>
- <string name="deny" msgid="6632259981847676572">"Odbij"</string>
- <string name="permission_request_notification_title" msgid="1810025922441048273">"Zatražena je dozvola"</string>
- <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Zatražena je dozvola\nza nalog <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
- <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"<xliff:g id="APP">%1$s</xliff:g> traži dozvolu \nza nalog <xliff:g id="ACCOUNT">%2$s</xliff:g>."</string>
- <string name="forward_intent_to_owner" msgid="4620359037192871015">"Koristite ovu aplikaciju izvan poslovnog profila"</string>
- <string name="forward_intent_to_work" msgid="3620262405636021151">"Koristite ovu aplikaciju na poslovnom profilu"</string>
- <string name="input_method_binding_label" msgid="1166731601721983656">"Metod unosa"</string>
- <string name="sync_binding_label" msgid="469249309424662147">"Sinhronizacija"</string>
- <string name="accessibility_binding_label" msgid="1974602776545801715">"Pristupačnost"</string>
- <string name="wallpaper_binding_label" msgid="1197440498000786738">"Pozadina"</string>
- <string name="chooser_wallpaper" msgid="3082405680079923708">"Promena pozadine"</string>
- <string name="notification_listener_binding_label" msgid="2702165274471499713">"Monitor obaveštenja"</string>
- <string name="vr_listener_binding_label" msgid="8013112996671206429">"Obrađivač za virtuelnu realnost"</string>
- <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Dobavljač uslova"</string>
- <string name="notification_ranker_binding_label" msgid="432708245635563763">"Usluga rangiranja obaveštenja"</string>
- <string name="vpn_title" msgid="5906991595291514182">"VPN je aktiviran"</string>
- <string name="vpn_title_long" msgid="6834144390504619998">"Aplikacija <xliff:g id="APP">%s</xliff:g> je aktivirala VPN"</string>
- <string name="vpn_text" msgid="2275388920267251078">"Dodirnite da biste upravljali mrežom."</string>
- <string name="vpn_text_long" msgid="278540576806169831">"Povezano sa sesijom <xliff:g id="SESSION">%s</xliff:g>. Dodirnite da biste upravljali mrežom."</string>
- <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Povezivanje stalno uključenog VPN-a..."</string>
- <string name="vpn_lockdown_connected" msgid="2853127976590658469">"Stalno uključen VPN je povezan"</string>
- <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Veza sa uvek uključenim VPN-om je prekinuta"</string>
- <string name="vpn_lockdown_error" msgid="4453048646854247947">"Povezivanje na stalno uključeni VPN nije uspelo"</string>
- <string name="vpn_lockdown_config" msgid="8331697329868252169">"Promenite podešavanja VPN-a"</string>
- <string name="upload_file" msgid="8651942222301634271">"Odaberi fajl"</string>
- <string name="no_file_chosen" msgid="4146295695162318057">"Nije izabrana nijedna datoteka"</string>
- <string name="reset" msgid="3865826612628171429">"Resetuj"</string>
- <string name="submit" msgid="862795280643405865">"Pošalji"</string>
- <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Aplikacija za vožnju je pokrenuta"</string>
- <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Dodirnite da biste izašli iz aplikacije za vožnju."</string>
- <string name="back_button_label" msgid="4078224038025043387">"Nazad"</string>
+ <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Приказ преко других апликација"</string>
+ <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"Апликација <xliff:g id="NAME">%s</xliff:g> се приказује преко других апликација"</string>
+ <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> се приказује преко других апл."</string>
+ <string name="alert_windows_notification_message" msgid="6538171456970725333">"Ако не желите ову функцију за <xliff:g id="NAME">%s</xliff:g>, додирните да бисте отворили подешавања и искључили је."</string>
+ <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Искључи"</string>
+ <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Проверава се <xliff:g id="NAME">%s</xliff:g>…"</string>
+ <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Прегледа се актуелни садржај"</string>
+ <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Анализира се меморијски простор за медије"</string>
+ <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Нови/а <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> не ради"</string>
+ <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Додирните да бисте подесили"</string>
+ <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Изаберите да бисте подесили"</string>
+ <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Можда морате да реформатирате уређај. Додирните да бисте избацили."</string>
+ <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"За чување слика, видео снимака, музике и другог садржаја"</string>
+ <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Прегледајте медијске фајлове"</string>
+ <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Проблем са: <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не ради"</string>
+ <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Додирните да бисте исправили"</string>
+ <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"Медиј <xliff:g id="NAME">%s</xliff:g> је оштећен. Изаберите да га поправите."</string>
+ <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"Можда морате да реформатирате уређај. Додирните да бисте избацили."</string>
+ <string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"Откривенo: <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> не ради"</string>
+ <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"Додирните да бисте подесили."</string>
+ <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Изаберите да бисте подесили уређај <xliff:g id="NAME">%s</xliff:g> у подржаном формату."</string>
+ <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Можда морате да реформатирате уређај"</string>
+ <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"Уређај <xliff:g id="NAME">%s</xliff:g> је неочекивано уклоњен"</string>
+ <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Избаците медијум пре него што га уклоните да не бисте изгубили садржај"</string>
+ <string name="ext_media_nomedia_notification_title" msgid="742671636376975890">"<xliff:g id="NAME">%s</xliff:g> је уклоњен/а"</string>
+ <string name="ext_media_nomedia_notification_message" msgid="2832724384636625852">"Неке функције можда неће исправно радити. Уметните нов меморијски уређај."</string>
+ <string name="ext_media_unmounting_notification_title" msgid="4147986383917892162">"Избацује се <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_unmounting_notification_message" msgid="5717036261538754203">"Не уклањајте"</string>
+ <string name="ext_media_init_action" msgid="2312974060585056709">"Активирај"</string>
+ <string name="ext_media_unmount_action" msgid="966992232088442745">"Избаци"</string>
+ <string name="ext_media_browse_action" msgid="344865351947079139">"Истражи"</string>
+ <string name="ext_media_seamless_action" msgid="8837030226009268080">"Промените излаз"</string>
+ <string name="ext_media_missing_title" msgid="3209472091220515046">"<xliff:g id="NAME">%s</xliff:g> недостаје"</string>
+ <string name="ext_media_missing_message" msgid="4408988706227922909">"Поново уметните уређај"</string>
+ <string name="ext_media_move_specific_title" msgid="8492118544775964250">"Преноси се <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_move_title" msgid="2682741525619033637">"Подаци се преносе"</string>
+ <string name="ext_media_move_success_title" msgid="4901763082647316767">"Пренос садржаја је готов"</string>
+ <string name="ext_media_move_success_message" msgid="9159542002276982979">"Садржај је премешен на: <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_move_failure_title" msgid="3184577479181333665">"Премештање садржаја није успело"</string>
+ <string name="ext_media_move_failure_message" msgid="4197306718121869335">"Пробајте да поново преместите садржај"</string>
+ <string name="ext_media_status_removed" msgid="241223931135751691">"Уклоњен је"</string>
+ <string name="ext_media_status_unmounted" msgid="8145812017295835941">"Избачен је"</string>
+ <string name="ext_media_status_checking" msgid="159013362442090347">"Проверава се..."</string>
+ <string name="ext_media_status_mounted" msgid="3459448555811203459">"Спреман је"</string>
+ <string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"Само за читање"</string>
+ <string name="ext_media_status_bad_removal" msgid="508448566481406245">"Уклоњен је на небезбедан начин"</string>
+ <string name="ext_media_status_unmountable" msgid="7043574843541087748">"Оштећен је"</string>
+ <string name="ext_media_status_unsupported" msgid="5460509911660539317">"Није подржан"</string>
+ <string name="ext_media_status_ejecting" msgid="7532403368044013797">"Избацује се..."</string>
+ <string name="ext_media_status_formatting" msgid="774148701503179906">"Форматира се..."</string>
+ <string name="ext_media_status_missing" msgid="6520746443048867314">"Није уметнут"</string>
+ <string name="activity_list_empty" msgid="4219430010716034252">"Није пронађена ниједна подударна активност."</string>
+ <string name="permlab_route_media_output" msgid="8048124531439513118">"усмеравање излаза медија"</string>
+ <string name="permdesc_route_media_output" msgid="1759683269387729675">"Дозвољава апликацији да усмерава излаз медија на друге спољне уређаје."</string>
+ <string name="permlab_readInstallSessions" msgid="7279049337895583621">"читање сесија инсталирања"</string>
+ <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Дозвољава апликацији да чита сесије инсталирања. То јој дозвољава да види детаље о активним инсталацијама пакета."</string>
+ <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"захтевање пакета за инсталирање"</string>
+ <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Омогућава да апликација захтева инсталацију пакета."</string>
+ <string name="permlab_requestDeletePackages" msgid="2541172829260106795">"захтевање брисања пакета"</string>
+ <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Омогућава да апликација захтева брисање пакета."</string>
+ <string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"тражење дозволе за игнорисање оптимизација батерије"</string>
+ <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Дозвољава апликацији да тражи дозволу за игнорисање оптимизација батерије за ту апликацију."</string>
+ <string name="permlab_queryAllPackages" msgid="2928450604653281650">"слање упита за све пакете"</string>
+ <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Дозвољава апликацији да види све инсталиране пакете."</string>
+ <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Додирните двапут за контролу зумирања"</string>
+ <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Није могуће додати виџет."</string>
+ <string name="ime_action_go" msgid="5536744546326495436">"Иди"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Претражи"</string>
+ <string name="ime_action_send" msgid="8456843745664334138">"Пошаљи"</string>
+ <string name="ime_action_next" msgid="4169702997635728543">"Даље"</string>
+ <string name="ime_action_done" msgid="6299921014822891569">"Готово"</string>
+ <string name="ime_action_previous" msgid="6548799326860401611">"Претходно"</string>
+ <string name="ime_action_default" msgid="8265027027659800121">"Изврши"</string>
+ <string name="dial_number_using" msgid="6060769078933953531">"Бирај број\nкористећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="create_contact_using" msgid="6200708808003692594">"Направите контакт\nкористећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Следеће апликације захтевају дозволу за приступ налогу, како сада, тако и убудуће."</string>
+ <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Желите да одобрите овај захтев?"</string>
+ <string name="grant_permissions_header_text" msgid="3420736827804657201">"Захтев за приступ"</string>
+ <string name="allow" msgid="6195617008611933762">"Дозволи"</string>
+ <string name="deny" msgid="6632259981847676572">"Одбиј"</string>
+ <string name="permission_request_notification_title" msgid="1810025922441048273">"Затражена је дозвола"</string>
+ <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Затражена је дозвола\nза налог <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+ <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"<xliff:g id="APP">%1$s</xliff:g> тражи дозволу \nза налог <xliff:g id="ACCOUNT">%2$s</xliff:g>."</string>
+ <string name="forward_intent_to_owner" msgid="4620359037192871015">"Користите ову апликацију изван пословног профила"</string>
+ <string name="forward_intent_to_work" msgid="3620262405636021151">"Користите ову апликацију на пословном профилу"</string>
+ <string name="input_method_binding_label" msgid="1166731601721983656">"Метод уноса"</string>
+ <string name="sync_binding_label" msgid="469249309424662147">"Синхронизација"</string>
+ <string name="accessibility_binding_label" msgid="1974602776545801715">"Приступачност"</string>
+ <string name="wallpaper_binding_label" msgid="1197440498000786738">"Позадина"</string>
+ <string name="chooser_wallpaper" msgid="3082405680079923708">"Промена позадине"</string>
+ <string name="notification_listener_binding_label" msgid="2702165274471499713">"Монитор обавештења"</string>
+ <string name="vr_listener_binding_label" msgid="8013112996671206429">"Обрађивач за виртуелну реалност"</string>
+ <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Добављач услова"</string>
+ <string name="notification_ranker_binding_label" msgid="432708245635563763">"Услуга рангирања обавештења"</string>
+ <string name="vpn_title" msgid="5906991595291514182">"VPN је активиран"</string>
+ <string name="vpn_title_long" msgid="6834144390504619998">"Апликација <xliff:g id="APP">%s</xliff:g> је активирала VPN"</string>
+ <string name="vpn_text" msgid="2275388920267251078">"Додирните да бисте управљали мрежом."</string>
+ <string name="vpn_text_long" msgid="278540576806169831">"Повезано са сесијом <xliff:g id="SESSION">%s</xliff:g>. Додирните да бисте управљали мрежом."</string>
+ <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Повезивање стално укљученог VPN-а..."</string>
+ <string name="vpn_lockdown_connected" msgid="2853127976590658469">"Стално укључен VPN је повезан"</string>
+ <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Веза са увек укљученим VPN-ом је прекинута"</string>
+ <string name="vpn_lockdown_error" msgid="4453048646854247947">"Повезивање на стално укључени VPN није успело"</string>
+ <string name="vpn_lockdown_config" msgid="8331697329868252169">"Промените подешавања VPN-а"</string>
+ <string name="upload_file" msgid="8651942222301634271">"Одабери фајл"</string>
+ <string name="no_file_chosen" msgid="4146295695162318057">"Није изабрана ниједна датотека"</string>
+ <string name="reset" msgid="3865826612628171429">"Ресетуј"</string>
+ <string name="submit" msgid="862795280643405865">"Пошаљи"</string>
+ <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Апликација за вожњу је покренута"</string>
+ <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Додирните да бисте изашли из апликације за вожњу."</string>
+ <string name="back_button_label" msgid="4078224038025043387">"Назад"</string>
<string name="next_button_label" msgid="6040209156399907780">"Next"</string>
- <string name="skip_button_label" msgid="3566599811326688389">"Preskoči"</string>
- <string name="no_matches" msgid="6472699895759164599">"Nema podudaranja"</string>
- <string name="find_on_page" msgid="5400537367077438198">"Pronađi na stranici"</string>
- <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# podudaranje}one{# od {total}}few{# od {total}}other{# od {total}}}"</string>
- <string name="action_mode_done" msgid="2536182504764803222">"Gotovo"</string>
- <string name="progress_erasing" msgid="6891435992721028004">"Briše se deljeni memorijski prostor…"</string>
- <string name="share" msgid="4157615043345227321">"Deli"</string>
- <string name="find" msgid="5015737188624767706">"Pronađi"</string>
- <string name="websearch" msgid="5624340204512793290">"Veb-pretraga"</string>
- <string name="find_next" msgid="5341217051549648153">"Pronađi sledeće"</string>
- <string name="find_previous" msgid="4405898398141275532">"Pronađi prethodno"</string>
- <string name="gpsNotifTicker" msgid="3207361857637620780">"Zahtev za lokaciju od korisnika <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="gpsNotifTitle" msgid="1590033371665669570">"Zahtev za lokaciju"</string>
- <string name="gpsNotifMessage" msgid="7346649122793758032">"Zahteva <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
- <string name="gpsVerifYes" msgid="3719843080744112940">"Da"</string>
- <string name="gpsVerifNo" msgid="1671201856091564741">"Ne"</string>
- <string name="sync_too_many_deletes" msgid="6999440774578705300">"Premašeno je ograničenje za brisanje"</string>
- <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Postoje izbrisane stavke (<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>) za <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, nalog <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Šta želite da uradite?"</string>
- <string name="sync_really_delete" msgid="5657871730315579051">"Izbriši stavke"</string>
- <string name="sync_undo_deletes" msgid="5786033331266418896">"Opozovi brisanja"</string>
- <string name="sync_do_nothing" msgid="4528734662446469646">"Ne radi ništa za sada"</string>
- <string name="choose_account_label" msgid="5557833752759831548">"Izaberite nalog"</string>
- <string name="add_account_label" msgid="4067610644298737417">"Dodaj nalog"</string>
- <string name="add_account_button_label" msgid="322390749416414097">"Dodaj nalog"</string>
- <string name="number_picker_increment_button" msgid="7621013714795186298">"Povećavanje"</string>
- <string name="number_picker_decrement_button" msgid="5116948444762708204">"Smanjivanje"</string>
- <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> dodirnite i zadržite."</string>
- <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Prevucite nagore da biste povećali, a nadole da biste smanjili."</string>
- <string name="time_picker_increment_minute_button" msgid="7195870222945784300">"Povećavanje minuta"</string>
- <string name="time_picker_decrement_minute_button" msgid="230925389943411490">"Smanjivanje minuta"</string>
- <string name="time_picker_increment_hour_button" msgid="3063572723197178242">"Povećavanje sati"</string>
- <string name="time_picker_decrement_hour_button" msgid="584101766855054412">"Smanjivanje sati"</string>
- <string name="time_picker_increment_set_pm_button" msgid="5889149366900376419">"Podesi po podne"</string>
- <string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"Podesi pre podne"</string>
- <string name="date_picker_increment_month_button" msgid="3447263316096060309">"Povećavanje meseca"</string>
- <string name="date_picker_decrement_month_button" msgid="6531888937036883014">"Smanjivanje meseca"</string>
- <string name="date_picker_increment_day_button" msgid="4349336637188534259">"Povećavanje dana"</string>
- <string name="date_picker_decrement_day_button" msgid="6840253837656637248">"Smanjivanje dana"</string>
- <string name="date_picker_increment_year_button" msgid="7608128783435372594">"Povećavanje godine"</string>
- <string name="date_picker_decrement_year_button" msgid="4102586521754172684">"Smanjivanje godine"</string>
- <string name="date_picker_prev_month_button" msgid="3418694374017868369">"Prethodni mesec"</string>
- <string name="date_picker_next_month_button" msgid="4858207337779144840">"Sledeći mesec"</string>
+ <string name="skip_button_label" msgid="3566599811326688389">"Прескочи"</string>
+ <string name="no_matches" msgid="6472699895759164599">"Нема подударања"</string>
+ <string name="find_on_page" msgid="5400537367077438198">"Пронађи на страници"</string>
+ <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# подударање}one{# од {total}}few{# од {total}}other{# од {total}}}"</string>
+ <string name="action_mode_done" msgid="2536182504764803222">"Готово"</string>
+ <string name="progress_erasing" msgid="6891435992721028004">"Брише се дељени меморијски простор…"</string>
+ <string name="share" msgid="4157615043345227321">"Дели"</string>
+ <string name="find" msgid="5015737188624767706">"Пронађи"</string>
+ <string name="websearch" msgid="5624340204512793290">"Веб-претрага"</string>
+ <string name="find_next" msgid="5341217051549648153">"Пронађи следеће"</string>
+ <string name="find_previous" msgid="4405898398141275532">"Пронађи претходно"</string>
+ <string name="gpsNotifTicker" msgid="3207361857637620780">"Захтев за локацију од корисника <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="1590033371665669570">"Захтев за локацију"</string>
+ <string name="gpsNotifMessage" msgid="7346649122793758032">"Захтева <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="3719843080744112940">"Да"</string>
+ <string name="gpsVerifNo" msgid="1671201856091564741">"Не"</string>
+ <string name="sync_too_many_deletes" msgid="6999440774578705300">"Премашено је ограничење за брисање"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Постоје избрисане ставке (<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>) за <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, налог <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Шта желите да урадите?"</string>
+ <string name="sync_really_delete" msgid="5657871730315579051">"Избриши ставке"</string>
+ <string name="sync_undo_deletes" msgid="5786033331266418896">"Опозови брисања"</string>
+ <string name="sync_do_nothing" msgid="4528734662446469646">"Не ради ништа за сада"</string>
+ <string name="choose_account_label" msgid="5557833752759831548">"Изаберите налог"</string>
+ <string name="add_account_label" msgid="4067610644298737417">"Додај налог"</string>
+ <string name="add_account_button_label" msgid="322390749416414097">"Додај налог"</string>
+ <string name="number_picker_increment_button" msgid="7621013714795186298">"Повећавање"</string>
+ <string name="number_picker_decrement_button" msgid="5116948444762708204">"Смањивање"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> додирните и задржите."</string>
+ <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Превуците нагоре да бисте повећали, а надоле да бисте смањили."</string>
+ <string name="time_picker_increment_minute_button" msgid="7195870222945784300">"Повећавање минута"</string>
+ <string name="time_picker_decrement_minute_button" msgid="230925389943411490">"Смањивање минута"</string>
+ <string name="time_picker_increment_hour_button" msgid="3063572723197178242">"Повећавање сати"</string>
+ <string name="time_picker_decrement_hour_button" msgid="584101766855054412">"Смањивање сати"</string>
+ <string name="time_picker_increment_set_pm_button" msgid="5889149366900376419">"Подеси по подне"</string>
+ <string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"Подеси пре подне"</string>
+ <string name="date_picker_increment_month_button" msgid="3447263316096060309">"Повећавање месеца"</string>
+ <string name="date_picker_decrement_month_button" msgid="6531888937036883014">"Смањивање месеца"</string>
+ <string name="date_picker_increment_day_button" msgid="4349336637188534259">"Повећавање дана"</string>
+ <string name="date_picker_decrement_day_button" msgid="6840253837656637248">"Смањивање дана"</string>
+ <string name="date_picker_increment_year_button" msgid="7608128783435372594">"Повећавање године"</string>
+ <string name="date_picker_decrement_year_button" msgid="4102586521754172684">"Смањивање године"</string>
+ <string name="date_picker_prev_month_button" msgid="3418694374017868369">"Претходни месец"</string>
+ <string name="date_picker_next_month_button" msgid="4858207337779144840">"Следећи месец"</string>
<string name="keyboardview_keycode_alt" msgid="8997420058584292385">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"Otkaži"</string>
- <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"Izbriši"</string>
- <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Gotovo"</string>
- <string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Promena režima"</string>
+ <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"Откажи"</string>
+ <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"Избриши"</string>
+ <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Готово"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Промена режима"</string>
<string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="168054869339091055">"Enter"</string>
- <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Izaberite aplikaciju"</string>
- <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Nije moguće pokrenuti <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Deli sa"</string>
- <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Deli sa aplikacijom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="content_description_sliding_handle" msgid="982510275422590757">"Klizna ručica. Dodirnite i zadržite."</string>
- <string name="description_target_unlock_tablet" msgid="7431571180065859551">"Prevucite da biste otključali."</string>
- <string name="action_bar_home_description" msgid="1501655419158631974">"Kretanje do Početne"</string>
- <string name="action_bar_up_description" msgid="6611579697195026932">"Kretanje nagore"</string>
- <string name="action_menu_overflow_description" msgid="4579536843510088170">"Još opcija"</string>
+ <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Изаберите апликацију"</string>
+ <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Није могуће покренути <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Дели са"</string>
+ <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Дели са апликацијом <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="content_description_sliding_handle" msgid="982510275422590757">"Клизна ручица. Додирните и задржите."</string>
+ <string name="description_target_unlock_tablet" msgid="7431571180065859551">"Превуците да бисте откључали."</string>
+ <string name="action_bar_home_description" msgid="1501655419158631974">"Кретање до Почетне"</string>
+ <string name="action_bar_up_description" msgid="6611579697195026932">"Кретање нагоре"</string>
+ <string name="action_menu_overflow_description" msgid="4579536843510088170">"Још опција"</string>
<string name="action_bar_home_description_format" msgid="5087107531331621803">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="4346835454749569826">"%1$s, %2$s, %3$s"</string>
- <string name="storage_internal" msgid="8490227947584914460">"Unutrašnji deljeni memorijski prostor"</string>
- <string name="storage_sd_card" msgid="3404740277075331881">"SD kartica"</string>
- <string name="storage_sd_card_label" msgid="7526153141147470509">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartica"</string>
- <string name="storage_usb_drive" msgid="448030813201444573">"USB disk"</string>
- <string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB disk"</string>
- <string name="storage_usb" msgid="2391213347883616886">"USB memorija"</string>
- <string name="extract_edit_menu_button" msgid="63954536535863040">"Izmeni"</string>
- <string name="data_usage_warning_title" msgid="9034893717078325845">"Upozorenje na potrošnju podataka"</string>
- <string name="data_usage_warning_body" msgid="1669325367188029454">"Potrošili ste <xliff:g id="APP">%s</xliff:g> podataka"</string>
- <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Dostigli ste ograničenje podataka"</string>
- <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Nema više WiFi podataka"</string>
- <string name="data_usage_limit_body" msgid="3567699582000085710">"Podaci su pauzirani tokom ostatka ciklusa"</string>
- <string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"Potrošili ste mobilne podatke"</string>
- <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"Potrošili ste WiFi podatke"</string>
- <string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"Prekoračili ste <xliff:g id="SIZE">%s</xliff:g> od podešenog ograničenja"</string>
- <string name="data_usage_restricted_title" msgid="126711424380051268">"Pozadinski podaci su ograničeni"</string>
- <string name="data_usage_restricted_body" msgid="5338694433686077733">"Dodirnite za uklanjanje ograničenja."</string>
- <string name="data_usage_rapid_title" msgid="2950192123248740375">"Velika potrošnja mob. podataka"</string>
- <string name="data_usage_rapid_body" msgid="3886676853263693432">"Aplikacije su potrošile više podataka nego obično"</string>
- <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"Aplikacija <xliff:g id="APP">%s</xliff:g> je potrošila više podataka nego obično"</string>
- <string name="ssl_certificate" msgid="5690020361307261997">"Bezbednosni sertifikat"</string>
- <string name="ssl_certificate_is_valid" msgid="7293675884598527081">"Ovaj sertifikat je važeći."</string>
- <string name="issued_to" msgid="5975877665505297662">"Izdato za:"</string>
- <string name="common_name" msgid="1486334593631798443">"Uobičajeni naziv:"</string>
- <string name="org_name" msgid="7526331696464255245">"Organizacija:"</string>
- <string name="org_unit" msgid="995934486977223076">"Organizaciona jedinica:"</string>
- <string name="issued_by" msgid="7872459822431585684">"Izdao/la:"</string>
- <string name="validity_period" msgid="1717724283033175968">"Važnost:"</string>
- <string name="issued_on" msgid="5855489688152497307">"Izdato:"</string>
- <string name="expires_on" msgid="1623640879705103121">"Ističe:"</string>
- <string name="serial_number" msgid="3479576915806623429">"Serijski broj:"</string>
- <string name="fingerprints" msgid="148690767172613723">"Digitalni otisci:"</string>
- <string name="sha256_fingerprint" msgid="7103976380961964600">"SHA-256 otisak prsta:"</string>
- <string name="sha1_fingerprint" msgid="2339915142825390774">"SHA-1 otisak prsta:"</string>
- <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Prikaži sve"</string>
- <string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Izbor aktivnosti"</string>
- <string name="share_action_provider_share_with" msgid="1904096863622941880">"Deli sa"</string>
- <string name="sending" msgid="206925243621664438">"Slanje..."</string>
- <string name="launchBrowserDefault" msgid="6328349989932924119">"Želite li da pokrenete pregledač?"</string>
- <string name="SetupCallDefault" msgid="5581740063237175247">"Želite li da prihvatite poziv?"</string>
- <string name="activity_resolver_use_always" msgid="5575222334666843269">"Uvek"</string>
- <string name="activity_resolver_use_once" msgid="948462794469672658">"Samo jednom"</string>
- <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s ne podržava poslovni profil"</string>
- <string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"Tablet"</string>
- <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
- <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
- <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Zvučnici bazne stanice"</string>
+ <string name="storage_internal" msgid="8490227947584914460">"Унутрашњи дељени меморијски простор"</string>
+ <string name="storage_sd_card" msgid="3404740277075331881">"SD картица"</string>
+ <string name="storage_sd_card_label" msgid="7526153141147470509">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD картица"</string>
+ <string name="storage_usb_drive" msgid="448030813201444573">"USB диск"</string>
+ <string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB диск"</string>
+ <string name="storage_usb" msgid="2391213347883616886">"USB меморија"</string>
+ <string name="extract_edit_menu_button" msgid="63954536535863040">"Измени"</string>
+ <string name="data_usage_warning_title" msgid="9034893717078325845">"Упозорење на потрошњу података"</string>
+ <string name="data_usage_warning_body" msgid="1669325367188029454">"Потрошили сте <xliff:g id="APP">%s</xliff:g> података"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Достигли сте ограничење података"</string>
+ <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Нема више WiFi података"</string>
+ <string name="data_usage_limit_body" msgid="3567699582000085710">"Подаци су паузирани током остатка циклуса"</string>
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"Потрошили сте мобилне податке"</string>
+ <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"Потрошили сте WiFi податке"</string>
+ <string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"Прекорачили сте <xliff:g id="SIZE">%s</xliff:g> од подешеног ограничења"</string>
+ <string name="data_usage_restricted_title" msgid="126711424380051268">"Позадински подаци су ограничени"</string>
+ <string name="data_usage_restricted_body" msgid="5338694433686077733">"Додирните за уклањање ограничења."</string>
+ <string name="data_usage_rapid_title" msgid="2950192123248740375">"Велика потрошња моб. података"</string>
+ <string name="data_usage_rapid_body" msgid="3886676853263693432">"Апликације су потрошиле више података него обично"</string>
+ <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"Апликација <xliff:g id="APP">%s</xliff:g> је потрошила више података него обично"</string>
+ <string name="ssl_certificate" msgid="5690020361307261997">"Безбедносни сертификат"</string>
+ <string name="ssl_certificate_is_valid" msgid="7293675884598527081">"Овај сертификат је важећи."</string>
+ <string name="issued_to" msgid="5975877665505297662">"Издато за:"</string>
+ <string name="common_name" msgid="1486334593631798443">"Уобичајени назив:"</string>
+ <string name="org_name" msgid="7526331696464255245">"Организација:"</string>
+ <string name="org_unit" msgid="995934486977223076">"Организациона јединица:"</string>
+ <string name="issued_by" msgid="7872459822431585684">"Издао/ла:"</string>
+ <string name="validity_period" msgid="1717724283033175968">"Важност:"</string>
+ <string name="issued_on" msgid="5855489688152497307">"Издато:"</string>
+ <string name="expires_on" msgid="1623640879705103121">"Истиче:"</string>
+ <string name="serial_number" msgid="3479576915806623429">"Серијски број:"</string>
+ <string name="fingerprints" msgid="148690767172613723">"Дигитални отисци:"</string>
+ <string name="sha256_fingerprint" msgid="7103976380961964600">"SHA-256 отисак прста:"</string>
+ <string name="sha1_fingerprint" msgid="2339915142825390774">"SHA-1 отисак прста:"</string>
+ <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Прикажи све"</string>
+ <string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Избор активности"</string>
+ <string name="share_action_provider_share_with" msgid="1904096863622941880">"Дели са"</string>
+ <string name="sending" msgid="206925243621664438">"Слање..."</string>
+ <string name="launchBrowserDefault" msgid="6328349989932924119">"Желите ли да покренете прегледач?"</string>
+ <string name="SetupCallDefault" msgid="5581740063237175247">"Желите ли да прихватите позив?"</string>
+ <string name="activity_resolver_use_always" msgid="5575222334666843269">"Увек"</string>
+ <string name="activity_resolver_use_once" msgid="948462794469672658">"Само једном"</string>
+ <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s не подржава пословни профил"</string>
+ <string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"Таблет"</string>
+ <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ТВ"</string>
+ <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Телефон"</string>
+ <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Звучници базне станице"</string>
<string name="default_audio_route_name_hdmi" msgid="5474470558160717850">"HDMI"</string>
- <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Slušalice"</string>
+ <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Слушалице"</string>
<string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
- <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"Bluetooth audio"</string>
- <string name="wireless_display_route_description" msgid="8297563323032966831">"Bežični ekran"</string>
- <string name="media_route_button_content_description" msgid="2299223698196869956">"Prebacuj"</string>
- <string name="media_route_chooser_title" msgid="6646594924991269208">"Povežite sa uređajem"</string>
- <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Prebacite ekran na uređaj"</string>
- <string name="media_route_chooser_searching" msgid="6119673534251329535">"Traženje uređaja…"</string>
- <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Podešavanja"</string>
- <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Prekini vezu"</string>
- <string name="media_route_status_scanning" msgid="8045156315309594482">"Skeniranje..."</string>
- <string name="media_route_status_connecting" msgid="5845597961412010540">"Povezuje se..."</string>
- <string name="media_route_status_available" msgid="1477537663492007608">"Dostupna"</string>
- <string name="media_route_status_not_available" msgid="480912417977515261">"Nisu dostupne"</string>
- <string name="media_route_status_in_use" msgid="6684112905244944724">"U upotrebi"</string>
- <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"Ugrađeni ekran"</string>
- <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI ekran"</string>
- <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"Postavljeni element br. <xliff:g id="ID">%1$d</xliff:g>"</string>
+ <string name="default_audio_route_category_name" msgid="5241740395748134483">"Систем"</string>
+ <string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"Bluetooth аудио"</string>
+ <string name="wireless_display_route_description" msgid="8297563323032966831">"Бежични екран"</string>
+ <string name="media_route_button_content_description" msgid="2299223698196869956">"Пребацуј"</string>
+ <string name="media_route_chooser_title" msgid="6646594924991269208">"Повежите са уређајем"</string>
+ <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Пребаците екран на уређај"</string>
+ <string name="media_route_chooser_searching" msgid="6119673534251329535">"Тражење уређаја…"</string>
+ <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Подешавања"</string>
+ <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Прекини везу"</string>
+ <string name="media_route_status_scanning" msgid="8045156315309594482">"Скенирање..."</string>
+ <string name="media_route_status_connecting" msgid="5845597961412010540">"Повезује се..."</string>
+ <string name="media_route_status_available" msgid="1477537663492007608">"Доступна"</string>
+ <string name="media_route_status_not_available" msgid="480912417977515261">"Нису доступне"</string>
+ <string name="media_route_status_in_use" msgid="6684112905244944724">"У употреби"</string>
+ <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"Уграђени екран"</string>
+ <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI екран"</string>
+ <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"Постављени елемент бр. <xliff:g id="ID">%1$d</xliff:g>"</string>
<string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>×<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
- <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", bezbedno"</string>
- <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Zaboravljeni šablon"</string>
- <string name="kg_wrong_pattern" msgid="1342812634464179931">"Pogrešan šablon"</string>
- <string name="kg_wrong_password" msgid="2384677900494439426">"Pogrešna lozinka"</string>
- <string name="kg_wrong_pin" msgid="3680925703673166482">"Pogrešan PIN"</string>
- <string name="kg_pattern_instructions" msgid="8366024510502517748">"Nacrtajte šablon"</string>
- <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Unesite PIN SIM kartice"</string>
- <string name="kg_pin_instructions" msgid="7355933174673539021">"Unesite PIN"</string>
- <string name="kg_password_instructions" msgid="7179782578809398050">"Unesite lozinku"</string>
- <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM kartica je sada onemogućena. Unesite PUK kôd da biste nastavili. Za detalje kontaktirajte operatera."</string>
- <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Unesite željeni PIN kôd"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Potvrdite željeni PIN kôd"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Otključavanje SIM kartice…"</string>
- <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"PIN kôd je netačan."</string>
- <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Unesite PIN koji ima od 4 do 8 brojeva."</string>
- <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK kôd treba da ima 8 brojeva."</string>
- <string name="kg_invalid_puk" msgid="4809502818518963344">"Ponovo unesite ispravni PUK kôd. Ponovljeni pokušaji će trajno onemogućiti SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN kodovi se ne podudaraju"</string>
- <string name="kg_login_too_many_attempts" msgid="699292728290654121">"Previše pokušaja unosa šablona"</string>
- <string name="kg_login_instructions" msgid="3619844310339066827">"Da biste otključali, prijavite se pomoću Google naloga."</string>
- <string name="kg_login_username_hint" msgid="1765453775467133251">"Korisničko ime (imejl adresa)"</string>
- <string name="kg_login_password_hint" msgid="3330530727273164402">"Lozinka"</string>
- <string name="kg_login_submit_button" msgid="893611277617096870">"Prijavi me"</string>
- <string name="kg_login_invalid_input" msgid="8292367491901220210">"Nevažeće korisničko ime ili lozinka."</string>
- <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Zaboravili ste korisničko ime ili lozinku?\nPosetite adresu "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="kg_login_checking_password" msgid="4676010303243317253">"Provera naloga…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Uneli ste netačni PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Uneli ste netačnu lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Nacrtali ste šablon za otključavanje netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunde/i."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Pokušali ste da otključate tablet netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešna(ih) pokušaja tablet će biti resetovan na fabrička podešavanja i svi korisnički podaci će biti izgubljeni."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Broj vaših neuspešnih pokušaja da otključate Android TV uređaj: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Broj preostalih neuspešnih pokušaja posle kojih će se Android TV resetovati na fabrička podešavanja i svi podaci korisnika će biti izgubljeni: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Pokušali ste da otključate telefon netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Posle još <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešna(ih) pokušaja telefon će biti resetovan na fabrička podešavanja i svi korisnički podaci će biti izgubljeni."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Pokušali ste da otključate tablet netačno <xliff:g id="NUMBER">%d</xliff:g> puta. Tablet će sada biti vraćen na podrazumevana fabrička podešavanja."</string>
- <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Broj vaših neuspešnih pokušaja da otključate Android TV uređaj: <xliff:g id="NUMBER">%d</xliff:g>. Android TV uređaj će se sada resetovati na fabrička podešavanja."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Pokušali ste da otključate telefon netačno <xliff:g id="NUMBER">%d</xliff:g> puta. Telefon će sada biti vraćen na podrazumevana fabrička podešavanja."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Nacrtali ste šablon za otključavanje netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Posle još <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešna(ih) pokušaja, od vas će biti zatraženo da otključate tablet pomoću naloga e-pošte.\n\nProbajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunde/i."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još puta (<xliff:g id="NUMBER_1">%2$d</xliff:g>), zatražićemo da otključate telefon pomoću Android TV uređaja.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Nacrtali ste šablon za otključavanje netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Posle još <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešna(ih) pokušaja, od vas će biti zatraženo da otključate telefon pomoću naloga e-pošte.\n\nProbajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunde/i."</string>
+ <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", безбедно"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Заборављени шаблон"</string>
+ <string name="kg_wrong_pattern" msgid="1342812634464179931">"Погрешан шаблон"</string>
+ <string name="kg_wrong_password" msgid="2384677900494439426">"Погрешна лозинка"</string>
+ <string name="kg_wrong_pin" msgid="3680925703673166482">"Погрешан PIN"</string>
+ <string name="kg_pattern_instructions" msgid="8366024510502517748">"Нацртајте шаблон"</string>
+ <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Унесите PIN SIM картице"</string>
+ <string name="kg_pin_instructions" msgid="7355933174673539021">"Унесите PIN"</string>
+ <string name="kg_password_instructions" msgid="7179782578809398050">"Унесите лозинку"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM картица је сада онемогућена. Унесите PUK кôд да бисте наставили. За детаље контактирајте оператера."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Унесите жељени PIN кôд"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Потврдите жељени PIN кôд"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Откључавање SIM картице…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"PIN кôд је нетачан."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Унесите PIN који има од 4 до 8 бројева."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK кôд треба да има 8 бројева."</string>
+ <string name="kg_invalid_puk" msgid="4809502818518963344">"Поново унесите исправни PUK кôд. Поновљени покушаји ће трајно онемогућити SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN кодови се не подударају"</string>
+ <string name="kg_login_too_many_attempts" msgid="699292728290654121">"Превише покушаја уноса шаблона"</string>
+ <string name="kg_login_instructions" msgid="3619844310339066827">"Да бисте откључали, пријавите се помоћу Google налога."</string>
+ <string name="kg_login_username_hint" msgid="1765453775467133251">"Корисничко име (имејл адреса)"</string>
+ <string name="kg_login_password_hint" msgid="3330530727273164402">"Лозинка"</string>
+ <string name="kg_login_submit_button" msgid="893611277617096870">"Пријави ме"</string>
+ <string name="kg_login_invalid_input" msgid="8292367491901220210">"Неважеће корисничко име или лозинка."</string>
+ <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Заборавили сте корисничко име или лозинку?\nПосетите адресу "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="4676010303243317253">"Провера налога…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Унели сте нетачни PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Унели сте нетачну лозинку <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Нацртали сте шаблон за откључавање нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунде/и."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Покушали сте да откључате таблет нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Након још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја таблет ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Број ваших неуспешних покушаја да откључате Android TV уређај: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Број преосталих неуспешних покушаја после којих ће се Android TV ресетовати на фабричка подешавања и сви подаци корисника ће бити изгубљени: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Покушали сте да откључате телефон нетачно <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешна(их) покушаја телефон ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Покушали сте да откључате таблет нетачно <xliff:g id="NUMBER">%d</xliff:g> пута. Таблет ће сада бити враћен на подразумевана фабричка подешавања."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Број ваших неуспешних покушаја да откључате Android TV уређај: <xliff:g id="NUMBER">%d</xliff:g>. Android TV уређај ће се сада ресетовати на фабричка подешавања."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Покушали сте да откључате телефон нетачно <xliff:g id="NUMBER">%d</xliff:g> пута. Телефон ће сада бити враћен на подразумевана фабричка подешавања."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Нацртали сте шаблон за откључавање нетачно <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="4670840383567106114">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још пута (<xliff:g id="NUMBER_1">%2$d</xliff:g>), затражићемо да откључате телефон помоћу Android TV уређаја.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Нацртали сте шаблон за откључавање нетачно <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="4503708889934976866">" – "</string>
- <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ukloni"</string>
- <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite da pojačate zvuk iznad preporučenog nivoa?\n\nSlušanje glasne muzike duže vreme može da vam ošteti sluh."</string>
- <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li da koristite prečicu za pristupačnost?"</string>
- <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kada je prečica uključena, pritisnite oba dugmeta za jačinu zvuka da biste pokrenuli funkciju pristupačnosti."</string>
- <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Želite da uključite prečicu za funkcije pristupačnosti?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Ako zadržite oba tastera za jačinu zvuka par sekundi, uključiće se funkcije pristupačnosti. To može da promeni način rada uređaja.\n\nPostojeće funkcije:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nMožete da promenite izabrane funkcije u odeljku Podešavanja > Pristupačnost."</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Уклони"</string>
+ <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Желите да појачате звук изнад препорученог нивоа?\n\nСлушање гласне музике дуже време може да вам оштети слух."</string>
+ <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Желите ли да користите пречицу за приступачност?"</string>
+ <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Када је пречица укључена, притисните оба дугмета за јачину звука да бисте покренули функцију приступачности."</string>
+ <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Желите да укључите пречицу за функције приступачности?"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Ако задржите оба тастера за јачину звука пар секунди, укључиће се функције приступачности. То може да промени начин рада уређаја.\n\nПостојеће функције:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nМожете да промените изабране функције у одељку Подешавања > Приступачност."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
- <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Želite da uključite prečicu za uslugu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
- <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ako zadržite oba tastera za jačinu zvuka par sekundi, uključuje se <xliff:g id="SERVICE">%1$s</xliff:g>, funkcija pristupačnosti. To može da promeni način rada uređaja.\n\nMožete da promenite funkciju na koju se odnosi ova prečica u odeljku Podešavanja > Pristupačnost."</string>
- <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Uključi"</string>
- <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ne uključuj"</string>
- <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"UKLJUČENO"</string>
- <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ISKLJUČENO"</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Želite li da dozvolite da usluga <xliff:g id="SERVICE">%1$s</xliff:g> ima potpunu kontrolu nad uređajem?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Potpuna kontrola je primerena za aplikacije koje vam pomažu kod usluga pristupačnosti, ali ne i za većinu aplikacija."</string>
- <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Pregledaj i kontroliši ekran"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Može da čita sav sadržaj na ekranu i prikazuje ga u drugim aplikacijama."</string>
- <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Pregledaj i obavljaj radnje"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Može da prati interakcije sa aplikacijom ili senzorom hardvera i koristi aplikacije umesto vas."</string>
- <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dozvoli"</string>
- <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odbij"</string>
- <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Dodirnite neku funkciju da biste počeli da je koristite:"</string>
- <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Odaberite funkcije koje ćete koristiti sa dugmetom Pristupačnost"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odaberite funkcije za prečicu tasterom jačine zvuka"</string>
- <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Usluga <xliff:g id="SERVICE_NAME">%s</xliff:g> je isključena"</string>
- <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Izmenite prečice"</string>
- <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gotovo"</string>
- <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečicu"</string>
- <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
- <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
- <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boja"</string>
- <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jednom rukom"</string>
- <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamnjeno"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
- <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite oba tastera za jačinu zvuka tri sekunde da biste koristili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću dva prsta prevucite nagore od dna ekrana):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću tri prsta prevucite nagore od dna ekrana):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Da biste prelazili sa jedne funkcije na drugu, dodirnite i zadržite dugme Pristupačnost."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Da biste prelazili sa jedne funkcije na drugu, prevucite nagore pomoću dva prsta i zadržite."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Da biste prelazili sa jedne funkcije na drugu, prevucite nagore pomoću tri prsta i zadržite."</string>
- <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećanje"</string>
- <string name="user_switched" msgid="7249833311585228097">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
- <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
- <string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljuje se <xliff:g id="NAME">%1$s</xliff:g>…"</string>
- <string name="owner_name" msgid="8713560351570795743">"Vlasnik"</string>
- <string name="guest_name" msgid="8502103277839834324">"Gost"</string>
- <string name="error_message_title" msgid="4082495589294631966">"Greška"</string>
- <string name="error_message_change_not_allowed" msgid="843159705042381454">"Administrator nije dozvolio ovu promenu"</string>
- <string name="app_not_found" msgid="3429506115332341800">"Nije pronađena nijedna aplikacija koja bi mogla da obavi ovu radnju"</string>
- <string name="revoke" msgid="5526857743819590458">"Opozovi"</string>
+ <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Желите да укључите пречицу за услугу <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ако задржите оба тастера за јачину звука пар секунди, укључује се <xliff:g id="SERVICE">%1$s</xliff:g>, функција приступачности. То може да промени начин рада уређаја.\n\nМожете да промените функцију на коју се односи ова пречица у одељку Подешавања > Приступачност."</string>
+ <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Укључи"</string>
+ <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Не укључуј"</string>
+ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"УКЉУЧЕНО"</string>
+ <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ИСКЉУЧЕНО"</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Желите ли да дозволите да услуга <xliff:g id="SERVICE">%1$s</xliff:g> има потпуну контролу над уређајем?"</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Потпуна контрола је примерена за апликације које вам помажу код услуга приступачности, али не и за већину апликација."</string>
+ <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Прегледај и контролиши екран"</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Може да чита сав садржај на екрану и приказује га у другим апликацијама."</string>
+ <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Прегледај и обављај радње"</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Може да прати интеракције са апликацијом или сензором хардвера и користи апликације уместо вас."</string>
+ <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Дозволи"</string>
+ <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Одбиј"</string>
+ <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Додирните неку функцију да бисте почели да је користите:"</string>
+ <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Одаберите функције које ћете користити са дугметом Приступачност"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Одаберите функције за пречицу тастером јачине звука"</string>
+ <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Услуга <xliff:g id="SERVICE_NAME">%s</xliff:g> је искључена"</string>
+ <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Измените пречице"</string>
+ <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Готово"</string>
+ <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Искључи пречицу"</string>
+ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи пречицу"</string>
+ <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија боја"</string>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"Корекција боја"</string>
+ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим једном руком"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додатно затамњено"</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
+ <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Притисните и задржите оба тастера за јачину звука три секунде да бисте користили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изаберите функцију која ће се користити када додирнете дугме Приступачност:"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу два прста превуците нагоре од дна екрана):"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу три прста превуците нагоре од дна екрана):"</string>
+ <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Да бисте прелазили са једне функције на другу, додирните и задржите дугме Приступачност."</string>
+ <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Да бисте прелазили са једне функције на другу, превуците нагоре помоћу два прста и задржите."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Да бисте прелазили са једне функције на другу, превуците нагоре помоћу три прста и задржите."</string>
+ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увећање"</string>
+ <string name="user_switched" msgid="7249833311585228097">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="user_switching_message" msgid="1912993630661332336">"Пребацивање на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+ <string name="user_logging_out_message" msgid="7216437629179710359">"Одјављује се <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+ <string name="owner_name" msgid="8713560351570795743">"Власник"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Гост"</string>
+ <string name="error_message_title" msgid="4082495589294631966">"Грешка"</string>
+ <string name="error_message_change_not_allowed" msgid="843159705042381454">"Администратор није дозволио ову промену"</string>
+ <string name="app_not_found" msgid="3429506115332341800">"Није пронађена ниједна апликација која би могла да обави ову радњу"</string>
+ <string name="revoke" msgid="5526857743819590458">"Опозови"</string>
<string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string>
<string name="mediasize_iso_a1" msgid="4063589931031977223">"ISO A1"</string>
<string name="mediasize_iso_a2" msgid="2779860175680233980">"ISO A2"</string>
@@ -1820,480 +1820,480 @@
<string name="mediasize_japanese_kaku2" msgid="7477551750461028312">"Kaku2"</string>
<string name="mediasize_japanese_you4" msgid="5552111912684384833">"You4"</string>
<string name="mediasize_japanese_l" msgid="1326765321473431817">"L"</string>
- <string name="mediasize_unknown_portrait" msgid="3817016220446495613">"Nepoznata veličina, uspravno"</string>
- <string name="mediasize_unknown_landscape" msgid="1584741567225095325">"Nepoznata veličina, vodoravno"</string>
- <string name="write_fail_reason_cancelled" msgid="2344081488493969190">"Otkazano je"</string>
- <string name="write_fail_reason_cannot_write" msgid="432118118378451508">"Greška pri ispisivanju sadržaja"</string>
- <string name="reason_unknown" msgid="5599739807581133337">"nepoznato"</string>
- <string name="reason_service_unavailable" msgid="5288405248063804713">"Usluga štampanja nije omogućena"</string>
- <string name="print_service_installed_title" msgid="6134880817336942482">"Usluga <xliff:g id="NAME">%s</xliff:g> je instalirana"</string>
- <string name="print_service_installed_message" msgid="7005672469916968131">"Dodirnite da biste omogućili"</string>
- <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"Unesite PIN administratora"</string>
- <string name="restr_pin_enter_pin" msgid="373139384161304555">"Unesite PIN"</string>
- <string name="restr_pin_incorrect" msgid="3861383632940852496">"Netačno"</string>
- <string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"Aktuelni PIN"</string>
- <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"Novi PIN"</string>
- <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Potvrdite novi PIN"</string>
- <string name="restr_pin_create_pin" msgid="917067613896366033">"Napravite PIN za izmenu ograničenja"</string>
- <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PIN-ovi se ne podudaraju. Probajte ponovo."</string>
- <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN je prekratak. Mora da sadrži najmanje 4 cifre."</string>
- <string name="restr_pin_try_later" msgid="5897719962541636727">"Probajte ponovo kasnije"</string>
- <string name="immersive_cling_title" msgid="2307034298721541791">"Prikazuje se ceo ekran"</string>
- <string name="immersive_cling_description" msgid="7092737175345204832">"Da biste izašli, prevucite nadole odozgo."</string>
- <string name="immersive_cling_positive" msgid="7047498036346489883">"Važi"</string>
- <string name="done_label" msgid="7283767013231718521">"Gotovo"</string>
- <string name="hour_picker_description" msgid="5153757582093524635">"Kružni klizač za sate"</string>
- <string name="minute_picker_description" msgid="9029797023621927294">"Kružni klizač za minute"</string>
- <string name="select_hours" msgid="5982889657313147347">"Izaberite sate"</string>
- <string name="select_minutes" msgid="9157401137441014032">"Izaberite minute"</string>
- <string name="select_day" msgid="2060371240117403147">"Izaberite mesec i dan"</string>
- <string name="select_year" msgid="1868350712095595393">"Izaberite godinu"</string>
- <string name="deleted_key" msgid="9130083334943364001">"Izbrisali ste <xliff:g id="KEY">%1$s</xliff:g>"</string>
- <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> na poslu"</string>
- <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. poslovni imejl <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Traži PIN pre otkačinjanja"</string>
- <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži šablon za otključavanje pre otkačinjanja"</string>
- <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku pre otkačinjanja"</string>
- <string name="package_installed_device_owner" msgid="7035926868974878525">"Instalirao je administrator"</string>
- <string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je administrator"</string>
- <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je administrator"</string>
- <string name="confirm_battery_saver" msgid="5247976246208245754">"Potvrdi"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizuelne efekte, određene funkcije i neke mrežne veze."</string>
- <string name="battery_saver_description" msgid="8518809702138617167">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizuelne efekte, određene funkcije i neke mrežne veze."</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Da bi se smanjila potrošnja podataka, Ušteda podataka sprečava neke aplikacije da šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može da pristupa podacima, ali će to činiti ređe. Na primer, slike se neće prikazivati dok ih ne dodirnete."</string>
- <string name="data_saver_enable_title" msgid="7080620065745260137">"Želite da uključite Uštedu podataka?"</string>
- <string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string>
- <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Jedan minut (do {formattedTime})}one{# minut (do {formattedTime})}few{# minuta (do {formattedTime})}other{# minuta (do {formattedTime})}}"</string>
- <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{1 min (do {formattedTime})}one{# min (do {formattedTime})}few{# min (do {formattedTime})}other{# min (do {formattedTime})}}"</string>
- <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{1 sat (do {formattedTime})}one{# sat (do {formattedTime})}few{# sata (do {formattedTime})}other{# sati (do {formattedTime})}}"</string>
- <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{1 s (do {formattedTime})}one{# s (do {formattedTime})}few{# s (do {formattedTime})}other{# s (do {formattedTime})}}"</string>
- <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Jedan minut}one{# minut}few{# minuta}other{# minuta}}"</string>
- <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{1 min}one{# min}few{# min}other{# min}}"</string>
- <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{1 sat}one{# sat}few{# sata}other{# sati}}"</string>
- <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{1 s}one{# s}few{# s}other{# s}}"</string>
- <string name="zen_mode_until_next_day" msgid="1403042784161725038">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sledeći alarm)"</string>
- <string name="zen_mode_forever" msgid="740585666364912448">"Dok ne isključite"</string>
- <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dok ne isključite režim Ne uznemiravaj"</string>
+ <string name="mediasize_unknown_portrait" msgid="3817016220446495613">"Непозната величина, усправно"</string>
+ <string name="mediasize_unknown_landscape" msgid="1584741567225095325">"Непозната величина, водоравно"</string>
+ <string name="write_fail_reason_cancelled" msgid="2344081488493969190">"Отказано је"</string>
+ <string name="write_fail_reason_cannot_write" msgid="432118118378451508">"Грешка при исписивању садржаја"</string>
+ <string name="reason_unknown" msgid="5599739807581133337">"непознато"</string>
+ <string name="reason_service_unavailable" msgid="5288405248063804713">"Услуга штампања није омогућена"</string>
+ <string name="print_service_installed_title" msgid="6134880817336942482">"Услуга <xliff:g id="NAME">%s</xliff:g> је инсталирана"</string>
+ <string name="print_service_installed_message" msgid="7005672469916968131">"Додирните да бисте омогућили"</string>
+ <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"Унесите PIN администратора"</string>
+ <string name="restr_pin_enter_pin" msgid="373139384161304555">"Унесите PIN"</string>
+ <string name="restr_pin_incorrect" msgid="3861383632940852496">"Нетачно"</string>
+ <string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"Актуелни PIN"</string>
+ <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"Нови PIN"</string>
+ <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Потврдите нови PIN"</string>
+ <string name="restr_pin_create_pin" msgid="917067613896366033">"Направите PIN за измену ограничења"</string>
+ <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PIN-ови се не подударају. Пробајте поново."</string>
+ <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN је прекратак. Мора да садржи најмање 4 цифре."</string>
+ <string name="restr_pin_try_later" msgid="5897719962541636727">"Пробајте поново касније"</string>
+ <string name="immersive_cling_title" msgid="2307034298721541791">"Приказује се цео екран"</string>
+ <string name="immersive_cling_description" msgid="7092737175345204832">"Да бисте изашли, превуците надоле одозго."</string>
+ <string name="immersive_cling_positive" msgid="7047498036346489883">"Важи"</string>
+ <string name="done_label" msgid="7283767013231718521">"Готово"</string>
+ <string name="hour_picker_description" msgid="5153757582093524635">"Кружни клизач за сате"</string>
+ <string name="minute_picker_description" msgid="9029797023621927294">"Кружни клизач за минуте"</string>
+ <string name="select_hours" msgid="5982889657313147347">"Изаберите сате"</string>
+ <string name="select_minutes" msgid="9157401137441014032">"Изаберите минуте"</string>
+ <string name="select_day" msgid="2060371240117403147">"Изаберите месец и дан"</string>
+ <string name="select_year" msgid="1868350712095595393">"Изаберите годину"</string>
+ <string name="deleted_key" msgid="9130083334943364001">"Избрисали сте <xliff:g id="KEY">%1$s</xliff:g>"</string>
+ <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> на послу"</string>
+ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. пословни <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. пословни имејл <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Тражи PIN пре откачињања"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Тражи шаблон за откључавање пре откачињања"</string>
+ <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тражи лозинку пре откачињања"</string>
+ <string name="package_installed_device_owner" msgid="7035926868974878525">"Инсталирао је администратор"</string>
+ <string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирао је администратор"</string>
+ <string name="package_deleted_device_owner" msgid="2292335928930293023">"Избрисао је администратор"</string>
+ <string name="confirm_battery_saver" msgid="5247976246208245754">"Потврди"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Уштеда батерије укључује тамну тему и ограничава или искључује активности у позадини, неке визуелне ефекте, одређене функције и неке мрежне везе."</string>
+ <string name="battery_saver_description" msgid="8518809702138617167">"Уштеда батерије укључује тамну тему и ограничава или искључује активности у позадини, неке визуелне ефекте, одређене функције и неке мрежне везе."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Да би се смањила потрошња података, Уштеда података спречава неке апликације да шаљу или примају податке у позадини. Апликација коју тренутно користите може да приступа подацима, али ће то чинити ређе. На пример, слике се неће приказивати док их не додирнете."</string>
+ <string name="data_saver_enable_title" msgid="7080620065745260137">"Желите да укључите Уштеду података?"</string>
+ <string name="data_saver_enable_button" msgid="4399405762586419726">"Укључи"</string>
+ <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Један минут (до {formattedTime})}one{# минут (до {formattedTime})}few{# минута (до {formattedTime})}other{# минута (до {formattedTime})}}"</string>
+ <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{1 мин (до {formattedTime})}one{# мин (до {formattedTime})}few{# мин (до {formattedTime})}other{# мин (до {formattedTime})}}"</string>
+ <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{1 сат (до {formattedTime})}one{# сат (до {formattedTime})}few{# сата (до {formattedTime})}other{# сати (до {formattedTime})}}"</string>
+ <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{1 с (до {formattedTime})}one{# с (до {formattedTime})}few{# с (до {formattedTime})}other{# с (до {formattedTime})}}"</string>
+ <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Један минут}one{# минут}few{# минута}other{# минута}}"</string>
+ <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{1 мин}one{# мин}few{# мин}other{# мин}}"</string>
+ <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{1 сат}one{# сат}few{# сата}other{# сати}}"</string>
+ <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{1 с}one{# с}few{# с}other{# с}}"</string>
+ <string name="zen_mode_until_next_day" msgid="1403042784161725038">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_until" msgid="2250286190237669079">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="7046911727540499275">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (следећи аларм)"</string>
+ <string name="zen_mode_forever" msgid="740585666364912448">"Док не искључите"</string>
+ <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Док не искључите режим Не узнемиравај"</string>
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
- <string name="toolbar_collapse_description" msgid="8009920446193610996">"Skupi"</string>
- <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ne uznemiravaj"</string>
- <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Odmor"</string>
- <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Radni dan uveče"</string>
- <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string>
- <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Događaj"</string>
- <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spavanje"</string>
- <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvuke"</string>
- <string name="system_error_wipe_data" msgid="5910572292172208493">"Došlo je do internog problema u vezi sa uređajem i možda će biti nestabilan dok ne obavite resetovanje na fabrička podešavanja."</string>
- <string name="system_error_manufacturer" msgid="703545241070116315">"Došlo je do internog problema u vezi sa uređajem. Potražite detalje od proizvođača."</string>
- <string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"USSD zahtev je promenjen u običan poziv"</string>
- <string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"USSD zahtev je promenjen u SS zahtev"</string>
- <string name="stk_cc_ussd_to_ussd" msgid="8343001461299302472">"Promenjeno je u novi USSD zahtev"</string>
- <string name="stk_cc_ussd_to_dial_video" msgid="429118590323618623">"USSD zahtev je promenjen u video poziv"</string>
- <string name="stk_cc_ss_to_dial" msgid="4087396658768717077">"SS zahtev je promenjen u običan poziv"</string>
- <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS zahtev je promenjen u video poziv"</string>
- <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS zahtev je promenjen u USSD zahtev"</string>
- <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Promenjeno je u novi SS zahtev"</string>
- <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Upozorenje o „pecanju“"</string>
- <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Poslovni profil"</string>
- <string name="notification_alerted_content_description" msgid="6139691253611265992">"Obavešteno"</string>
- <string name="notification_verified_content_description" msgid="6401483602782359391">"Verifikovano"</string>
- <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Proširi"</string>
- <string name="expand_button_content_description_expanded" msgid="7484217944948667489">"Skupi"</string>
- <string name="expand_action_accessibility" msgid="1947657036871746627">"uključite/isključite proširenje"</string>
- <string name="usb_midi_peripheral_name" msgid="490523464968655741">"Android USB port za periferijske uređaje"</string>
+ <string name="toolbar_collapse_description" msgid="8009920446193610996">"Скупи"</string>
+ <string name="zen_mode_feature_name" msgid="3785547207263754500">"Не узнемиравај"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Одмор"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Радни дан увече"</string>
+ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Викенд"</string>
+ <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Догађај"</string>
+ <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Спавање"</string>
+ <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> искључује неке звуке"</string>
+ <string name="system_error_wipe_data" msgid="5910572292172208493">"Дошло је до интерног проблема у вези са уређајем и можда ће бити нестабилан док не обавите ресетовање на фабричка подешавања."</string>
+ <string name="system_error_manufacturer" msgid="703545241070116315">"Дошло је до интерног проблема у вези са уређајем. Потражите детаље од произвођача."</string>
+ <string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"USSD захтев је промењен у обичан позив"</string>
+ <string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"USSD захтев је промењен у SS захтев"</string>
+ <string name="stk_cc_ussd_to_ussd" msgid="8343001461299302472">"Промењено је у нови USSD захтев"</string>
+ <string name="stk_cc_ussd_to_dial_video" msgid="429118590323618623">"USSD захтев је промењен у видео позив"</string>
+ <string name="stk_cc_ss_to_dial" msgid="4087396658768717077">"SS захтев је промењен у обичан позив"</string>
+ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS захтев је промењен у видео позив"</string>
+ <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS захтев је промењен у USSD захтев"</string>
+ <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Промењено је у нови SS захтев"</string>
+ <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Упозорење о „пецању“"</string>
+ <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Пословни профил"</string>
+ <string name="notification_alerted_content_description" msgid="6139691253611265992">"Обавештено"</string>
+ <string name="notification_verified_content_description" msgid="6401483602782359391">"Верификовано"</string>
+ <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Прошири"</string>
+ <string name="expand_button_content_description_expanded" msgid="7484217944948667489">"Скупи"</string>
+ <string name="expand_action_accessibility" msgid="1947657036871746627">"укључите/искључите проширење"</string>
+ <string name="usb_midi_peripheral_name" msgid="490523464968655741">"Android USB порт за периферијске уређаје"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7557148557088787741">"Android"</string>
- <string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"USB port za periferijske uređaje"</string>
- <string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"Još opcija"</string>
- <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"Zatvori preklopni meni"</string>
- <string name="maximize_button_text" msgid="4258922519914732645">"Uvećaj"</string>
- <string name="close_button_text" msgid="10603510034455258">"Zatvori"</string>
+ <string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"USB порт за периферијске уређаје"</string>
+ <string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"Још опција"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"Затвори преклопни мени"</string>
+ <string name="maximize_button_text" msgid="4258922519914732645">"Увећај"</string>
+ <string name="close_button_text" msgid="10603510034455258">"Затвори"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
- <string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string>
- <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
- <string name="call_notification_decline_action" msgid="3700345945214000726">"Odbij"</string>
- <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini vezu"</string>
- <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string>
- <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv je u toku"</string>
- <string name="call_notification_screening_text" msgid="8396931408268940208">"Proverava se dolazni poziv"</string>
- <string name="default_notification_channel_label" msgid="3697928973567217330">"Nekategorizovano"</string>
- <string name="importance_from_user" msgid="2782756722448800447">"Vi podešavate važnost ovih obaveštenja."</string>
- <string name="importance_from_person" msgid="4235804979664465383">"Ovo je važno zbog ljudi koji učestvuju."</string>
- <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Prilagođeno obaveštenje o aplikaciji"</string>
- <string name="user_creation_account_exists" msgid="2239146360099708035">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik sa tim nalogom već postoji)?"</string>
- <string name="user_creation_adding" msgid="7305185499667958364">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
- <string name="supervised_user_creation_label" msgid="6884904353827427515">"Dodajte korisnika pod nadzorom"</string>
- <string name="language_selection_title" msgid="52674936078683285">"Dodajte jezik"</string>
- <string name="country_selection_title" msgid="5221495687299014379">"Podešavanje regiona"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"Unesite naziv jezika"</string>
- <string name="language_picker_section_suggested" msgid="6556199184638990447">"Predloženi"</string>
- <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"Predloženo"</string>
- <string name="language_picker_section_all" msgid="1985809075777564284">"Svi jezici"</string>
- <string name="region_picker_section_all" msgid="756441309928774155">"Svi regioni"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"Pretraži"</string>
- <string name="app_suspended_title" msgid="888873445010322650">"Aplikacija nije dostupna"</string>
- <string name="app_suspended_default_message" msgid="6451215678552004172">"Aplikacija <xliff:g id="APP_NAME_0">%1$s</xliff:g> trenutno nije dostupna. <xliff:g id="APP_NAME_1">%2$s</xliff:g> upravlja dostupnošću."</string>
- <string name="app_suspended_more_details" msgid="211260942831587014">"Saznajte više"</string>
- <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Opozovi pauziranje aplikacije"</string>
- <string name="work_mode_off_title" msgid="961171256005852058">"Uključujete poslovne aplikacije?"</string>
- <string name="work_mode_off_message" msgid="7319580997683623309">"Pristupajte poslovnim aplikacijama i obaveštenjima"</string>
- <string name="work_mode_turn_on" msgid="3662561662475962285">"Uključi"</string>
- <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
- <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
- <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – nije dostupno"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebna je dozvola"</string>
- <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nije dostupna"</string>
- <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Nastavite na telefonu"</string>
- <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon je nedostupan"</string>
- <string name="app_streaming_blocked_title_for_playstore_dialog" msgid="8149823099822897538">"Play prodavnica nije dostupna"</string>
- <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Podešavanja Android TV-a su nedostupna"</string>
- <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Podešavanja tableta su nedostupna"</string>
- <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Podešavanja telefona su nedostupna"</string>
- <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Ovoj aplikaciji trenutno ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na Android TV uređaju."</string>
- <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Ovoj aplikaciji trenutno ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na tabletu."</string>
- <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Ovoj aplikaciji trenutno ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na telefonu."</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ova aplikacija zahteva dodatnu bezbednost. Probajte na Android TV uređaju."</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ova aplikacija zahteva dodatnu bezbednost. Probajte na tabletu."</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ova aplikacija zahteva dodatnu bezbednost. Probajte na telefonu."</string>
- <string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Ovoj aplikaciji ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na Android TV uređaju."</string>
- <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Ovoj aplikaciji ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na tabletu."</string>
- <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ovoj aplikaciji ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na telefonu."</string>
- <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova aplikacija je napravljena za stariju verziju Android-a, pa možda neće raditi ispravno. Potražite ažuriranja ili kontaktirajte programera."</string>
- <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Potraži ažuriranje"</string>
- <string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
- <string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorite aplikaciju za SMS da biste pregledali"</string>
- <string name="profile_encrypted_title" msgid="9001208667521266472">"Neke funkcije su možda ograničene"</string>
- <string name="profile_encrypted_detail" msgid="5279730442756849055">"Poslovni profil je zaključan"</string>
- <string name="profile_encrypted_message" msgid="1128512616293157802">"Dodirom otklj. poslovni profil"</string>
- <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Povezano je sa proizvodom <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
- <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Dodirnite za pregled datoteka"</string>
- <string name="pin_target" msgid="8036028973110156895">"Zakači"</string>
- <string name="pin_specific_target" msgid="7824671240625957415">"Zakači aplikaciju <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="unpin_target" msgid="3963318576590204447">"Otkači"</string>
- <string name="unpin_specific_target" msgid="3859828252160908146">"Otkači aplikaciju <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="app_info" msgid="6113278084877079851">"Informacije o aplikaciji"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Одговори"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Видео"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Одбиј"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Прекини везу"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Долазни позив"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Позив је у току"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Проверава се долазни позив"</string>
+ <string name="default_notification_channel_label" msgid="3697928973567217330">"Некатегоризовано"</string>
+ <string name="importance_from_user" msgid="2782756722448800447">"Ви подешавате важност ових обавештења."</string>
+ <string name="importance_from_person" msgid="4235804979664465383">"Ово је важно због људи који учествују."</string>
+ <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Прилагођено обавештење о апликацији"</string>
+ <string name="user_creation_account_exists" msgid="2239146360099708035">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g> (корисник са тим налогом већ постоји)?"</string>
+ <string name="user_creation_adding" msgid="7305185499667958364">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
+ <string name="supervised_user_creation_label" msgid="6884904353827427515">"Додајте корисника под надзором"</string>
+ <string name="language_selection_title" msgid="52674936078683285">"Додајте језик"</string>
+ <string name="country_selection_title" msgid="5221495687299014379">"Подешавање региона"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"Унесите назив језика"</string>
+ <string name="language_picker_section_suggested" msgid="6556199184638990447">"Предложени"</string>
+ <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"Предложено"</string>
+ <string name="language_picker_section_all" msgid="1985809075777564284">"Сви језици"</string>
+ <string name="region_picker_section_all" msgid="756441309928774155">"Сви региони"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Претражи"</string>
+ <string name="app_suspended_title" msgid="888873445010322650">"Апликација није доступна"</string>
+ <string name="app_suspended_default_message" msgid="6451215678552004172">"Апликација <xliff:g id="APP_NAME_0">%1$s</xliff:g> тренутно није доступна. <xliff:g id="APP_NAME_1">%2$s</xliff:g> управља доступношћу."</string>
+ <string name="app_suspended_more_details" msgid="211260942831587014">"Сазнајте више"</string>
+ <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Опозови паузирање апликације"</string>
+ <string name="work_mode_off_title" msgid="961171256005852058">"Укључујете пословне апликације?"</string>
+ <string name="work_mode_off_message" msgid="7319580997683623309">"Приступајте пословним апликацијама и обавештењима"</string>
+ <string name="work_mode_turn_on" msgid="3662561662475962285">"Укључи"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Апликација није доступна"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> тренутно није доступна."</string>
+ <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – није доступно"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Потребна је дозвола"</string>
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камера није доступна"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Наставите на телефону"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофон је недоступан"</string>
+ <string name="app_streaming_blocked_title_for_playstore_dialog" msgid="8149823099822897538">"Play продавница није доступна"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Подешавања Android TV-а су недоступна"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Подешавања таблета су недоступна"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Подешавања телефона су недоступна"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Овој апликацији тренутно не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на Android TV уређају."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Овој апликацији тренутно не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на таблету."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Овој апликацији тренутно не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на телефону."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ова апликација захтева додатну безбедност. Пробајте на Android TV уређају."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ова апликација захтева додатну безбедност. Пробајте на таблету."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ова апликација захтева додатну безбедност. Пробајте на телефону."</string>
+ <string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Овој апликацији не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на Android TV уређају."</string>
+ <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Овој апликацији не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на таблету."</string>
+ <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Овој апликацији не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на телефону."</string>
+ <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ова апликација је направљена за старију верзију Android-а, па можда неће радити исправно. Потражите ажурирања или контактирајте програмера."</string>
+ <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Потражи ажурирање"</string>
+ <string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нове поруке"</string>
+ <string name="new_sms_notification_content" msgid="3197949934153460639">"Отворите апликацију за SMS да бисте прегледали"</string>
+ <string name="profile_encrypted_title" msgid="9001208667521266472">"Неке функције су можда ограничене"</string>
+ <string name="profile_encrypted_detail" msgid="5279730442756849055">"Пословни профил је закључан"</string>
+ <string name="profile_encrypted_message" msgid="1128512616293157802">"Додиром откљ. пословни профил"</string>
+ <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Повезано је са производом <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
+ <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Додирните за преглед датотека"</string>
+ <string name="pin_target" msgid="8036028973110156895">"Закачи"</string>
+ <string name="pin_specific_target" msgid="7824671240625957415">"Закачи апликацију <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="unpin_target" msgid="3963318576590204447">"Откачи"</string>
+ <string name="unpin_specific_target" msgid="3859828252160908146">"Откачи апликацију <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="app_info" msgid="6113278084877079851">"Информације о апликацији"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="demo_starting_message" msgid="6577581216125805905">"Pokrećemo demonstraciju..."</string>
- <string name="demo_restarting_message" msgid="1160053183701746766">"Resetujemo uređaj..."</string>
- <string name="suspended_widget_accessibility" msgid="6331451091851326101">"Vidžet <xliff:g id="LABEL">%1$s</xliff:g> je onemogućen"</string>
- <string name="conference_call" msgid="5731633152336490471">"Konferencijski poziv"</string>
- <string name="tooltip_popup_title" msgid="7863719020269945722">"Objašnjenje"</string>
- <string name="app_category_game" msgid="4534216074910244790">"Igre"</string>
- <string name="app_category_audio" msgid="8296029904794676222">"Muzika i audio"</string>
- <string name="app_category_video" msgid="2590183854839565814">"Filmovi i video"</string>
- <string name="app_category_image" msgid="7307840291864213007">"Slike"</string>
- <string name="app_category_social" msgid="2278269325488344054">"Društvene mreže i komunikacija"</string>
- <string name="app_category_news" msgid="1172762719574964544">"Novosti i časopisi"</string>
- <string name="app_category_maps" msgid="6395725487922533156">"Mape i navigacija"</string>
- <string name="app_category_productivity" msgid="1844422703029557883">"Produktivnost"</string>
- <string name="app_category_accessibility" msgid="6643521607848547683">"Pristupačnost"</string>
- <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Memorijski prostor uređaja"</string>
- <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje grešaka sa USB-a"</string>
- <string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
- <string name="time_picker_minute_label" msgid="8307452311269824553">"minut"</string>
- <string name="time_picker_header_text" msgid="9073802285051516688">"Podesite vreme"</string>
- <string name="time_picker_input_error" msgid="8386271930742451034">"Unesite važeće vreme"</string>
- <string name="time_picker_prompt_label" msgid="303588544656363889">"Unesite vreme"</string>
- <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Pređite u režim unosa teksta radi unosa vremena."</string>
- <string name="time_picker_radial_mode_description" msgid="1222342577115016953">"Pređite u režim sata radi unosa vremena."</string>
- <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Opcije automatskog popunjavanja"</string>
- <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Sačuvajte za automatsko popunjavanje"</string>
- <string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Sadržaj ne može automatski da se popuni"</string>
- <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Nema automatski popunjenih predloga"</string>
- <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Jedan automatski popunjen predlog}one{# automatski popunjen predlog}few{# automatski popunjena predloga}other{# automatski popunjenih predloga}}"</string>
- <string name="autofill_save_title" msgid="7719802414283739775">"Želite li da sačuvate u usluzi "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
- <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Želite li da sačuvate stavku <xliff:g id="TYPE">%1$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
- <string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
- <string name="autofill_save_title_with_3types" msgid="6598228952100102578">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
- <string name="autofill_update_title" msgid="3630695947047069136">"Želite li da ažurirate u usluzi "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
- <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Želite li da ažurirate stavku <xliff:g id="TYPE">%1$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
- <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Želite li da ažurirate stavke <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
- <string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Želite li da ažurirate ove stavke u usluzi "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
- <string name="autofill_save_yes" msgid="8035743017382012850">"Sačuvaj"</string>
- <string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string>
- <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne sada"</string>
- <string name="autofill_save_never" msgid="6821841919831402526">"Nikada"</string>
- <string name="autofill_update_yes" msgid="4608662968996874445">"Ažuriraj"</string>
- <string name="autofill_continue_yes" msgid="7914985605534510385">"Nastavi"</string>
- <string name="autofill_save_type_password" msgid="5624528786144539944">"lozinka"</string>
- <string name="autofill_save_type_address" msgid="3111006395818252885">"adresa"</string>
- <string name="autofill_save_type_credit_card" msgid="3583795235862046693">"kreditna kartica"</string>
- <string name="autofill_save_type_debit_card" msgid="3169397504133097468">"debitna kartica"</string>
- <string name="autofill_save_type_payment_card" msgid="6555012156728690856">"platna kartica"</string>
- <string name="autofill_save_type_generic_card" msgid="1019367283921448608">"kartica"</string>
- <string name="autofill_save_type_username" msgid="1018816929884640882">"korisničko ime"</string>
- <string name="autofill_save_type_email_address" msgid="1303262336895591924">"imejl adresa"</string>
- <string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"Ostanite mirni i potražite sklonište u okolini."</string>
- <string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"Odmah se sklonite iz priobalnih regiona i oblasti pored reka na neko bezbednije mesto, na primer, na neko uzvišenje."</string>
- <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"Ostanite mirni i potražite sklonište u okolini."</string>
- <string name="etws_primary_default_message_test" msgid="4583367373909549421">"Testiranje poruka u hitnim slučajevima"</string>
- <string name="notification_reply_button_accessibility" msgid="5235776156579456126">"Odgovori"</string>
+ <string name="demo_starting_message" msgid="6577581216125805905">"Покрећемо демонстрацију..."</string>
+ <string name="demo_restarting_message" msgid="1160053183701746766">"Ресетујемо уређај..."</string>
+ <string name="suspended_widget_accessibility" msgid="6331451091851326101">"Виџет <xliff:g id="LABEL">%1$s</xliff:g> је онемогућен"</string>
+ <string name="conference_call" msgid="5731633152336490471">"Конференцијски позив"</string>
+ <string name="tooltip_popup_title" msgid="7863719020269945722">"Објашњење"</string>
+ <string name="app_category_game" msgid="4534216074910244790">"Игре"</string>
+ <string name="app_category_audio" msgid="8296029904794676222">"Музика и аудио"</string>
+ <string name="app_category_video" msgid="2590183854839565814">"Филмови и видео"</string>
+ <string name="app_category_image" msgid="7307840291864213007">"Слике"</string>
+ <string name="app_category_social" msgid="2278269325488344054">"Друштвене мреже и комуникација"</string>
+ <string name="app_category_news" msgid="1172762719574964544">"Новости и часописи"</string>
+ <string name="app_category_maps" msgid="6395725487922533156">"Мапе и навигација"</string>
+ <string name="app_category_productivity" msgid="1844422703029557883">"Продуктивност"</string>
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Приступачност"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Меморијски простор уређаја"</string>
+ <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Отклањање грешака са USB-а"</string>
+ <string name="time_picker_hour_label" msgid="4208590187662336864">"сат"</string>
+ <string name="time_picker_minute_label" msgid="8307452311269824553">"минут"</string>
+ <string name="time_picker_header_text" msgid="9073802285051516688">"Подесите време"</string>
+ <string name="time_picker_input_error" msgid="8386271930742451034">"Унесите важеће време"</string>
+ <string name="time_picker_prompt_label" msgid="303588544656363889">"Унесите време"</string>
+ <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Пређите у режим уноса текста ради уноса времена."</string>
+ <string name="time_picker_radial_mode_description" msgid="1222342577115016953">"Пређите у режим сата ради уноса времена."</string>
+ <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Опције аутоматског попуњавања"</string>
+ <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Сачувајте за аутоматско попуњавање"</string>
+ <string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Садржај не може аутоматски да се попуни"</string>
+ <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Нема аутоматски попуњених предлога"</string>
+ <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Један аутоматски попуњен предлог}one{# аутоматски попуњен предлог}few{# аутоматски попуњена предлога}other{# аутоматски попуњених предлога}}"</string>
+ <string name="autofill_save_title" msgid="7719802414283739775">"Желите ли да сачувате у услузи "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Желите ли да сачувате ставку <xliff:g id="TYPE">%1$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Желите ли да сачувате ставке <xliff:g id="TYPE_0">%1$s</xliff:g> и <xliff:g id="TYPE_1">%2$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6598228952100102578">"Желите ли да сачувате ставке <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_update_title" msgid="3630695947047069136">"Желите ли да ажурирате у услузи "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Желите ли да ажурирате ставку <xliff:g id="TYPE">%1$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Желите ли да ажурирате ставке <xliff:g id="TYPE_0">%1$s</xliff:g> и <xliff:g id="TYPE_1">%2$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Желите ли да ажурирате ове ставке у услузи "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_yes" msgid="8035743017382012850">"Сачувај"</string>
+ <string name="autofill_save_no" msgid="9212826374207023544">"Не, хвала"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сада"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Никада"</string>
+ <string name="autofill_update_yes" msgid="4608662968996874445">"Ажурирај"</string>
+ <string name="autofill_continue_yes" msgid="7914985605534510385">"Настави"</string>
+ <string name="autofill_save_type_password" msgid="5624528786144539944">"лозинка"</string>
+ <string name="autofill_save_type_address" msgid="3111006395818252885">"адреса"</string>
+ <string name="autofill_save_type_credit_card" msgid="3583795235862046693">"кредитна картица"</string>
+ <string name="autofill_save_type_debit_card" msgid="3169397504133097468">"дебитна картица"</string>
+ <string name="autofill_save_type_payment_card" msgid="6555012156728690856">"платна картица"</string>
+ <string name="autofill_save_type_generic_card" msgid="1019367283921448608">"картица"</string>
+ <string name="autofill_save_type_username" msgid="1018816929884640882">"корисничко име"</string>
+ <string name="autofill_save_type_email_address" msgid="1303262336895591924">"имејл адреса"</string>
+ <string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"Останите мирни и потражите склониште у околини."</string>
+ <string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"Одмах се склоните из приобалних региона и области поред река на неко безбедније место, на пример, на неко узвишење."</string>
+ <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"Останите мирни и потражите склониште у околини."</string>
+ <string name="etws_primary_default_message_test" msgid="4583367373909549421">"Тестирање порука у хитним случајевима"</string>
+ <string name="notification_reply_button_accessibility" msgid="5235776156579456126">"Одговори"</string>
<string name="etws_primary_default_message_others" msgid="7958161706019130739"></string>
- <string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIM kartica nije prilagođena za glasovne usluge"</string>
- <string name="mmcc_imsi_unknown_in_hlr" msgid="227760698553988751">"SIM kartica nije podešena za glasovne usluge"</string>
- <string name="mmcc_illegal_ms" msgid="7509650265233909445">"SIM kartica nije prilagođena za glasovne usluge"</string>
- <string name="mmcc_illegal_me" msgid="6505557881889904915">"Telefon nije prilagođen za glasovne usluge"</string>
- <string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> nije dozvoljen"</string>
- <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> nije podešen"</string>
- <string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> nije dozvoljen"</string>
- <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> nije dozvoljen"</string>
- <string name="popup_window_default_title" msgid="6907717596694826919">"Iskačući prozor"</string>
- <string name="slice_more_content" msgid="3377367737876888459">"i još <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Aplikacija je vraćena na stariju verziju ili nije kompatibilna sa ovom prečicom"</string>
- <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Vraćanje prečice nije uspelo jer aplikacija ne podržava pravljenje rezervne kopije i vraćanje"</string>
- <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Vraćanje prečice nije uspelo jer se potpisi aplikacija ne podudaraju"</string>
- <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Vraćanje prečice nije uspelo"</string>
- <string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Prečica je onemogućena"</string>
- <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DEINSTALIRAJ"</string>
- <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IPAK OTVORI"</string>
- <string name="harmful_app_warning_title" msgid="8794823880881113856">"Otkrivena je štetna aplikacija"</string>
- <string name="log_access_confirmation_title" msgid="2343578467290592708">"Želite da dozvolite aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim evidencijama uređaja?"</string>
- <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Dozvoli jednokratan pristup"</string>
- <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne dozvoli"</string>
- <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Evidencije uređaja registruju šta se dešava na uređaju. Aplikacije mogu da koriste te evidencije da bi pronašle i rešile probleme.\n\nNeke evidencije mogu da sadrže osetljive informacije, pa pristup svim evidencijama uređaja treba da dozvoljavate samo aplikacijama u koje imate poverenja. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim evidencijama uređaja, ona i dalje može da pristupa sopstvenim evidencijama. Proizvođač uređaja će možda i dalje moći da pristupa nekim evidencijama ili informacijama na uređaju."</string>
- <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Evidencije uređaja registruju šta se dešava na uređaju. Aplikacije mogu da koriste te evidencije da bi pronašle i rešile probleme.\n\nNeke evidencije mogu da sadrže osetljive informacije, pa pristup svim evidencijama uređaja treba da dozvoljavate samo aplikacijama u koje imate poverenja. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim evidencijama uređaja, ona i dalje može da pristupa sopstvenim evidencijama. Proizvođač uređaja će možda i dalje moći da pristupa nekim evidencijama ili informacijama na uređaju.\n\nSaznajte više na g.co/android/devicelogs."</string>
- <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikazuj ponovo"</string>
- <string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi da prikazuje isečke iz aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string>
- <string name="screenshot_edit" msgid="7408934887203689207">"Izmeni"</string>
- <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Vibracija za pozive i obaveštenja je uključena"</string>
- <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Melodija zvona za pozive i obaveštenje je isključena"</string>
- <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistemske promene"</string>
- <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne uznemiravaj"</string>
- <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novo: Režim Ne uznemiravaj krije obaveštenja"</string>
- <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dodirnite da biste saznali više i promenili podešavanje."</string>
- <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režim Ne uznemiravaj je promenjen"</string>
- <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da biste proverili šta je blokirano."</string>
- <string name="review_notification_settings_title" msgid="5102557424459810820">"Pregledajte podešavanja obaveštenja"</string>
- <string name="review_notification_settings_text" msgid="5916244866751849279">"Od Android-a 13 aplikacije koje instalirate moraju da imaju dozvolu za slanje obaveštenja. Dodirnite da biste promenili ovu dozvolu za postojeće aplikacije."</string>
- <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Podseti me kasnije"</string>
- <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
- <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
- <string name="notification_app_name_settings" msgid="9088548800899952531">"Podešavanja"</string>
- <string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
- <string name="notification_appops_microphone_active" msgid="581333393214739332">"Mikrofon"</string>
- <string name="notification_appops_overlay_active" msgid="5571732753262836481">"prikazuje se na ekranu dok koristite druge aplikacije"</string>
- <string name="notification_feedback_indicator" msgid="663476517711323016">"Pošaljite povratne informacije"</string>
- <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"Ovo obaveštenje je unapređeno u Podrazumevano. Dodirnite da biste naveli povratne informacije."</string>
- <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Ovo obaveštenje je degradirano u Nečujno. Dodirnite da biste naveli povratne informacije."</string>
- <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Ovo obaveštenje je rangirano više. Dodirnite da biste naveli povratne informacije."</string>
- <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Ovo obaveštenje je rangirano niže. Dodirnite da biste naveli povratne informacije."</string>
- <string name="nas_upgrade_notification_title" msgid="8436359459300146555">"Poboljšana obaveštenja"</string>
- <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Predložene radnje i odgovore sada dobijate pomoću poboljšanih obaveštenja. Prilagodljiva obaveštenja za Android više nisu podržana."</string>
- <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Potvrdi"</string>
- <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Isključi"</string>
- <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
- <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Poboljšana obaveštenja su zamenila Android prilagodljiva obaveštenja u Android-u 12. Ova funkcija pokazuje predložene radnje i odgovore, i organizuje obaveštenja.\n\nPoboljšana obaveštenja mogu da pristupaju sadržaju obaveštenja, uključujući lične podatke poput imena kontakata i poruka. Ova funkcija može i da odbacuje obaveštenja ili da odgovara na njih, na primer, da se javlja na telefonske pozive i kontroliše režim Ne uznemiravaj."</string>
- <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obaveštenje o informacijama Rutinskog režima"</string>
- <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija će se možda isprazniti pre uobičajenog punjenja"</string>
- <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Ušteda baterije je aktivirana da bi se produžilo trajanje baterije"</string>
- <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ušteda baterije"</string>
- <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ušteda baterije je isključena"</string>
- <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Baterija telefona je dovoljno napunjena. Funkcije više nisu ograničene."</string>
- <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Baterija tableta je dovoljno napunjena. Funkcije više nisu ograničene."</string>
- <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Baterija uređaja je dovoljno napunjena. Funkcije više nisu ograničene."</string>
- <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
- <string name="mime_type_apk" msgid="3168784749499623902">"Android aplikacija"</string>
- <string name="mime_type_generic" msgid="4606589110116560228">"Datoteka"</string>
- <string name="mime_type_generic_ext" msgid="9220220924380909486">"<xliff:g id="EXTENSION">%1$s</xliff:g> datoteka"</string>
- <string name="mime_type_audio" msgid="4933450584432509875">"Audio datoteka"</string>
- <string name="mime_type_audio_ext" msgid="2615491023840514797">"<xliff:g id="EXTENSION">%1$s</xliff:g> audio datoteka"</string>
- <string name="mime_type_video" msgid="7071965726609428150">"Video"</string>
- <string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> video"</string>
- <string name="mime_type_image" msgid="2134307276151645257">"Slika"</string>
- <string name="mime_type_image_ext" msgid="5743552697560999471">"<xliff:g id="EXTENSION">%1$s</xliff:g> slika"</string>
- <string name="mime_type_compressed" msgid="8737300936080662063">"Arhiva"</string>
- <string name="mime_type_compressed_ext" msgid="4775627287994475737">"<xliff:g id="EXTENSION">%1$s</xliff:g> arhiva"</string>
- <string name="mime_type_document" msgid="3737256839487088554">"Dokument"</string>
- <string name="mime_type_document_ext" msgid="2398002765046677311">"<xliff:g id="EXTENSION">%1$s</xliff:g> dokument"</string>
- <string name="mime_type_spreadsheet" msgid="8188407519131275838">"Tabela"</string>
- <string name="mime_type_spreadsheet_ext" msgid="8720173181137254414">"<xliff:g id="EXTENSION">%1$s</xliff:g> tabela"</string>
- <string name="mime_type_presentation" msgid="1145384236788242075">"Prezentacija"</string>
- <string name="mime_type_presentation_ext" msgid="8761049335564371468">"<xliff:g id="EXTENSION">%1$s</xliff:g> prezentacija"</string>
- <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth ostaje uključen tokom režima rada u avionu"</string>
- <string name="car_loading_profile" msgid="8219978381196748070">"Učitava se"</string>
- <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # fajl}one{{file_name} + # fajl}few{{file_name} + # fajla}other{{file_name} + # fajlova}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nema preporučenih ljudi za deljenje"</string>
- <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista aplikacija"</string>
- <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Ova aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string>
- <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Početak"</string>
- <string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Nazad"</string>
- <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Nedavne aplikacije"</string>
- <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Obaveštenja"</string>
- <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Brza podešavanja"</string>
- <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dijalog napajanja"</string>
- <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključavanje ekrana"</string>
- <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimak ekrana"</string>
- <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Kuka za slušalice"</string>
- <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Prečica za pristupačnost na ekranu"</string>
- <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Alatka za biranje prečica za pristupačnost na ekranu"</string>
- <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečica za pristupačnost"</string>
- <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbaci traku sa obaveštenjima"</string>
- <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"nagore na D-pad-u"</string>
- <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"nadole na D-pad-u"</string>
- <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"nalevo na D-pad-u"</string>
- <string name="accessibility_system_action_dpad_right_label" msgid="9180196950365804081">"nadesno na D-pad-u"</string>
- <string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"centar na D-pad-u"</string>
- <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka sa naslovima aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je dodat u segment OGRANIČENO"</string>
+ <string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIM картица није прилагођена за гласовне услуге"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="227760698553988751">"SIM картица није подешена за гласовне услуге"</string>
+ <string name="mmcc_illegal_ms" msgid="7509650265233909445">"SIM картица није прилагођена за гласовне услуге"</string>
+ <string name="mmcc_illegal_me" msgid="6505557881889904915">"Телефон није прилагођен за гласовне услуге"</string>
+ <string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> није дозвољен"</string>
+ <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> није подешен"</string>
+ <string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> није дозвољен"</string>
+ <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> није дозвољен"</string>
+ <string name="popup_window_default_title" msgid="6907717596694826919">"Искачући прозор"</string>
+ <string name="slice_more_content" msgid="3377367737876888459">"и још <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+ <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Апликација је враћена на старију верзију или није компатибилна са овом пречицом"</string>
+ <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Враћање пречице није успело јер апликација не подржава прављење резервне копије и враћање"</string>
+ <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Враћање пречице није успело јер се потписи апликација не подударају"</string>
+ <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Враћање пречице није успело"</string>
+ <string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Пречица је онемогућена"</string>
+ <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ДЕИНСТАЛИРАЈ"</string>
+ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ИПАК ОТВОРИ"</string>
+ <string name="harmful_app_warning_title" msgid="8794823880881113856">"Откривена је штетна апликација"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Желите да дозволите апликацији <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> да приступа свим евиденцијама уређаја?"</string>
+ <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Дозволи једнократан приступ"</string>
+ <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дозволи"</string>
+ <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Евиденције уређаја региструју шта се дешава на уређају. Апликације могу да користе те евиденције да би пронашле и решиле проблеме.\n\nНеке евиденције могу да садрже осетљиве информације, па приступ свим евиденцијама уређаја треба да дозвољавате само апликацијама у које имате поверења. \n\nАко не дозволите овој апликацији да приступа свим евиденцијама уређаја, она и даље може да приступа сопственим евиденцијама. Произвођач уређаја ће можда и даље моћи да приступа неким евиденцијама или информацијама на уређају."</string>
+ <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Евиденције уређаја региструју шта се дешава на уређају. Апликације могу да користе те евиденције да би пронашле и решиле проблеме.\n\nНеке евиденције могу да садрже осетљиве информације, па приступ свим евиденцијама уређаја треба да дозвољавате само апликацијама у које имате поверења. \n\nАко не дозволите овој апликацији да приступа свим евиденцијама уређаја, она и даље може да приступа сопственим евиденцијама. Произвођач уређаја ће можда и даље моћи да приступа неким евиденцијама или информацијама на уређају.\n\nСазнајте више на g.co/android/devicelogs."</string>
+ <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Не приказуј поново"</string>
+ <string name="slices_permission_request" msgid="3677129866636153406">"Апликација <xliff:g id="APP_0">%1$s</xliff:g> жели да приказује исечке из апликације <xliff:g id="APP_2">%2$s</xliff:g>"</string>
+ <string name="screenshot_edit" msgid="7408934887203689207">"Измени"</string>
+ <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Вибрација за позиве и обавештења је укључена"</string>
+ <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Мелодија звона за позиве и обавештење је искључена"</string>
+ <string name="notification_channel_system_changes" msgid="2462010596920209678">"Системске промене"</string>
+ <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Не узнемиравај"</string>
+ <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Ново: Режим Не узнемиравај крије обавештења"</string>
+ <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Додирните да бисте сазнали више и променили подешавање."</string>
+ <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Режим Не узнемиравај је промењен"</string>
+ <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Додирните да бисте проверили шта је блокирано."</string>
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Прегледајте подешавања обавештења"</string>
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Од Android-а 13 апликације које инсталирате морају да имају дозволу за слање обавештења. Додирните да бисте променили ову дозволу за постојеће апликације."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Подсети ме касније"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Одбаци"</string>
+ <string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
+ <string name="notification_app_name_settings" msgid="9088548800899952531">"Подешавања"</string>
+ <string name="notification_appops_camera_active" msgid="8177643089272352083">"Камера"</string>
+ <string name="notification_appops_microphone_active" msgid="581333393214739332">"Микрофон"</string>
+ <string name="notification_appops_overlay_active" msgid="5571732753262836481">"приказује се на екрану док користите друге апликације"</string>
+ <string name="notification_feedback_indicator" msgid="663476517711323016">"Пошаљите повратне информације"</string>
+ <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"Ово обавештење је унапређено у Подразумевано. Додирните да бисте навели повратне информације."</string>
+ <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Ово обавештење је деградирано у Нечујно. Додирните да бисте навели повратне информације."</string>
+ <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Ово обавештење је рангирано више. Додирните да бисте навели повратне информације."</string>
+ <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Ово обавештење је рангирано ниже. Додирните да бисте навели повратне информације."</string>
+ <string name="nas_upgrade_notification_title" msgid="8436359459300146555">"Побољшана обавештења"</string>
+ <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Предложене радње и одговоре сада добијате помоћу побољшаних обавештења. Прилагодљива обавештења за Android више нису подржана."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Потврди"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Искључи"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Сазнајте више"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Побољшана обавештења су заменила Android прилагодљива обавештења у Android-у 12. Ова функција показује предложене радње и одговоре, и организује обавештења.\n\nПобољшана обавештења могу да приступају садржају обавештења, укључујући личне податке попут имена контаката и порука. Ова функција може и да одбацује обавештења или да одговара на њих, на пример, да се јавља на телефонске позиве и контролише режим Не узнемиравај."</string>
+ <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Обавештење о информацијама Рутинског режима"</string>
+ <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батерија ће се можда испразнити пре уобичајеног пуњења"</string>
+ <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Уштеда батерије је активирана да би се продужило трајање батерије"</string>
+ <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Уштеда батерије"</string>
+ <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Уштеда батерије је искључена"</string>
+ <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Батерија телефона је довољно напуњена. Функције више нису ограничене."</string>
+ <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Батерија таблета је довољно напуњена. Функције више нису ограничене."</string>
+ <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Батерија уређаја је довољно напуњена. Функције више нису ограничене."</string>
+ <string name="mime_type_folder" msgid="2203536499348787650">"Фолдер"</string>
+ <string name="mime_type_apk" msgid="3168784749499623902">"Android апликација"</string>
+ <string name="mime_type_generic" msgid="4606589110116560228">"Датотека"</string>
+ <string name="mime_type_generic_ext" msgid="9220220924380909486">"<xliff:g id="EXTENSION">%1$s</xliff:g> датотека"</string>
+ <string name="mime_type_audio" msgid="4933450584432509875">"Аудио датотека"</string>
+ <string name="mime_type_audio_ext" msgid="2615491023840514797">"<xliff:g id="EXTENSION">%1$s</xliff:g> аудио датотека"</string>
+ <string name="mime_type_video" msgid="7071965726609428150">"Видео"</string>
+ <string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> видео"</string>
+ <string name="mime_type_image" msgid="2134307276151645257">"Слика"</string>
+ <string name="mime_type_image_ext" msgid="5743552697560999471">"<xliff:g id="EXTENSION">%1$s</xliff:g> слика"</string>
+ <string name="mime_type_compressed" msgid="8737300936080662063">"Архива"</string>
+ <string name="mime_type_compressed_ext" msgid="4775627287994475737">"<xliff:g id="EXTENSION">%1$s</xliff:g> архива"</string>
+ <string name="mime_type_document" msgid="3737256839487088554">"Документ"</string>
+ <string name="mime_type_document_ext" msgid="2398002765046677311">"<xliff:g id="EXTENSION">%1$s</xliff:g> документ"</string>
+ <string name="mime_type_spreadsheet" msgid="8188407519131275838">"Табела"</string>
+ <string name="mime_type_spreadsheet_ext" msgid="8720173181137254414">"<xliff:g id="EXTENSION">%1$s</xliff:g> табела"</string>
+ <string name="mime_type_presentation" msgid="1145384236788242075">"Презентација"</string>
+ <string name="mime_type_presentation_ext" msgid="8761049335564371468">"<xliff:g id="EXTENSION">%1$s</xliff:g> презентација"</string>
+ <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth остаје укључен током режима рада у авиону"</string>
+ <string name="car_loading_profile" msgid="8219978381196748070">"Учитава се"</string>
+ <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # фајл}one{{file_name} + # фајл}few{{file_name} + # фајла}other{{file_name} + # фајлова}}"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Нема препоручених људи за дељење"</string>
+ <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Листа апликација"</string>
+ <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Ова апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string>
+ <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Почетак"</string>
+ <string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Назад"</string>
+ <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Недавне апликације"</string>
+ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Обавештења"</string>
+ <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Брза подешавања"</string>
+ <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Дијалог напајања"</string>
+ <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Закључавање екрана"</string>
+ <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Снимак екрана"</string>
+ <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Кука за слушалице"</string>
+ <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Пречица за приступачност на екрану"</string>
+ <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Алатка за бирање пречица за приступачност на екрану"</string>
+ <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Пречица за приступачност"</string>
+ <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Одбаци траку са обавештењима"</string>
+ <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"нагоре на D-pad-у"</string>
+ <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"надоле на D-pad-у"</string>
+ <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"налево на D-pad-у"</string>
+ <string name="accessibility_system_action_dpad_right_label" msgid="9180196950365804081">"надесно на D-pad-у"</string>
+ <string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"центар на D-pad-у"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Трака са насловима апликације <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> је додат у сегмент ОГРАНИЧЕНО"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
- <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"je poslao/la sliku"</string>
- <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Konverzacija"</string>
- <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupna konverzacija"</string>
+ <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"је послао/ла слику"</string>
+ <string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Конверзација"</string>
+ <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групна конверзација"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
- <string name="resolver_personal_tab" msgid="2051260504014442073">"Lično"</string>
- <string name="resolver_work_tab" msgid="2690019516263167035">"Poslovno"</string>
- <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Lični prikaz"</string>
- <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Prikaz za posao"</string>
- <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Blokira IT administrator"</string>
- <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Ovaj sadržaj ne može da se deli pomoću poslovnih aplikacija"</string>
- <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Ovaj sadržaj ne može da se otvara pomoću poslovnih aplikacija"</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Ovaj sadržaj ne može da se deli pomoću ličnih aplikacija"</string>
- <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Ovaj sadržaj ne može da se otvara pomoću ličnih aplikacija"</string>
- <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Poslovni profil je pauziran"</string>
- <string name="resolver_switch_on_work" msgid="463709043650610420">"Dodirnite da biste uključili"</string>
- <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nema poslovnih aplikacija"</string>
- <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nema ličnih aplikacija"</string>
- <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"Želite da na ličnom profilu otvorite: <xliff:g id="APP">%s</xliff:g>?"</string>
- <string name="miniresolver_open_in_work" msgid="4415223793669536559">"Želite da na poslovnom profilu otvorite: <xliff:g id="APP">%s</xliff:g>?"</string>
- <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Koristi lični pregledač"</string>
- <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Koristi poslovni pregledač"</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN za otključavanje SIM mreže"</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN za otključavanje podskupa SIM mreže"</string>
- <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN za otključavanje poslovne SIM kartice"</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ENTRY" msgid="973059024670737358">"PIN za otključavanje dobavljača usluge SIM kartice"</string>
- <string name="PERSOSUBSTATE_SIM_SIM_ENTRY" msgid="4487435301206073787">"PIN za otključavanje SIM kartice"</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ENTRY" msgid="768060297218652809">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ENTRY" msgid="7129527319490548930">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ENTRY" msgid="2876126640607573252">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="8952595089930109282">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_SIM_SIM_PUK_ENTRY" msgid="3013902515773728996">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK1_ENTRY" msgid="2974411408893410289">"PIN za otključavanje RUIM mreže 1"</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK2_ENTRY" msgid="687618528751880721">"PIN za otključavanje RUIM mreže 2"</string>
- <string name="PERSOSUBSTATE_RUIM_HRPD_ENTRY" msgid="6810596579655575381">"PIN za otključavanje RUIM hrpd-a"</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_ENTRY" msgid="2715929642540980259">"PIN za otključavanje poslovne RUIM kartice"</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ENTRY" msgid="8557791623303951590">"PIN za otključavanje RUIM kartice dobavljača usluge"</string>
- <string name="PERSOSUBSTATE_RUIM_RUIM_ENTRY" msgid="7382468767274580323">"PIN za otključavanje RUIM kartice"</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ENTRY" msgid="6730880791104286987">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ENTRY" msgid="6432126539782267026">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ENTRY" msgid="1730510161529488920">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="3369885925003346830">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ENTRY" msgid="9129139686191167829">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ENTRY" msgid="2869929685874615358">"Unesite PUK"</string>
- <string name="PERSOSUBSTATE_SIM_SPN_ENTRY" msgid="1238663472392741771">"PIN za otključavanje SPN-a"</string>
- <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ENTRY" msgid="3988705848553894358">"PIN za otključavanje SP ekvivalentnog matičnog PLMN-a"</string>
- <string name="PERSOSUBSTATE_SIM_ICCID_ENTRY" msgid="6186770686690993200">"PIN za otključavanje ICCID-a"</string>
- <string name="PERSOSUBSTATE_SIM_IMPI_ENTRY" msgid="7043865376145617024">"PIN za otključavanje IMPI-ja"</string>
- <string name="PERSOSUBSTATE_SIM_NS_SP_ENTRY" msgid="6144227308185112176">"PIN za otključavanje dobavljača usluge podskupa mreže"</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_IN_PROGRESS" msgid="4233355366318061180">"Zahteva se otključavanje SIM mreže…"</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_IN_PROGRESS" msgid="6742563947637715645">"Zahteva se otključavanje podskupa SIM mreže…"</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="2033399698172403560">"Zahteva se otključavanje dobavljača usluge SIM kartice…"</string>
- <string name="PERSOSUBSTATE_SIM_CORPORATE_IN_PROGRESS" msgid="4795977251920732254">"Zahteva se otključavanje poslovne SIM kartice…"</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_IN_PROGRESS" msgid="1090425878157254446">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_IN_PROGRESS" msgid="6476898876518094438">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_IN_PROGRESS" msgid="6006806734293747731">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_IN_PROGRESS" msgid="6546680489620881893">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_SIM_SIM_PUK_IN_PROGRESS" msgid="3506845511000727015">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_SIM_SIM_IN_PROGRESS" msgid="6709169861932992750">"Zahteva se otključavanje SIM kartice…"</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK1_IN_PROGRESS" msgid="4013870911606478520">"Zahteva se otključavanje RUIM mreže 1…"</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK2_IN_PROGRESS" msgid="9032651188219523434">"Zahteva se otključavanje RUIM mreže 2…"</string>
- <string name="PERSOSUBSTATE_RUIM_HRPD_IN_PROGRESS" msgid="6584576506344491207">"Zahteva se otključavanje RUIM hrpd-a…"</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="830981927724888114">"Zahteva se otključavanje RUIM kartice dobavljača usluge…"</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_IN_PROGRESS" msgid="7851790973098894802">"Zahteva se otključavanje poslovne RUIM kartice…"</string>
- <string name="PERSOSUBSTATE_SIM_SPN_IN_PROGRESS" msgid="1149560739586960121">"Zahteva se otključavanje SPN-a…"</string>
- <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_IN_PROGRESS" msgid="5708964693522116025">"Zahteva se otključavanje SP ekvivalentnog matičnog PLMN-a…"</string>
- <string name="PERSOSUBSTATE_SIM_ICCID_IN_PROGRESS" msgid="7288103122966483455">"Zahteva se otključavanje ICCID-a…"</string>
- <string name="PERSOSUBSTATE_SIM_IMPI_IN_PROGRESS" msgid="4036752174056147753">"Zahteva se otključavanje IMPI-ja…"</string>
- <string name="PERSOSUBSTATE_SIM_NS_SP_IN_PROGRESS" msgid="5089536274515338566">"Zahteva se otključavanje dobavljača usluge podskupa mreže…"</string>
- <string name="PERSOSUBSTATE_RUIM_RUIM_IN_PROGRESS" msgid="6737197986936251958">"Zahteva se otključavanje RUIM kartice…"</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_IN_PROGRESS" msgid="5658767775619998623">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_IN_PROGRESS" msgid="665978313257653727">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_IN_PROGRESS" msgid="3857142652251836850">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_IN_PROGRESS" msgid="2695664012344346788">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_IN_PROGRESS" msgid="2695678959963807782">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_IN_PROGRESS" msgid="1230605365926493599">"Zahteva se otključavanje pomoću PUK-a…"</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_ERROR" msgid="1924844017037151535">"Zahtev za otključavanje SIM mreže nije uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ERROR" msgid="3372797822292089708">"Zahtev za otključavanje podskupa SIM mreže je uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ERROR" msgid="1878443146720411381">"Zahtev za otključavanje dobavljača usluge SIM kartice nije uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_CORPORATE_ERROR" msgid="7664778312218023192">"Zahtev za otključavanje poslovne SIM kartice nije uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_SIM_ERROR" msgid="2472944311643350302">"Zahtev za otključavanje SIM kartice nije uspeo."</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK1_ERROR" msgid="828089694480999120">"Zahtev za otključavanje RUIM mreže 1 nije uspeo."</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK2_ERROR" msgid="17619001007092511">"Zahtev za otključavanje RUIM mreže 2 nije uspeo."</string>
- <string name="PERSOSUBSTATE_RUIM_HRPD_ERROR" msgid="807214229604353614">"Zahtev za otključavanje RUIM hrpd-a nije uspeo."</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_ERROR" msgid="8644184447744175747">"Zahtev za otključavanje poslovne RUIM kartice nije uspeo."</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ERROR" msgid="3801002648649640407">"Zahtev za otključavanje RUIM kartice dobavljača usluge nije uspeo."</string>
- <string name="PERSOSUBSTATE_RUIM_RUIM_ERROR" msgid="707397021218680753">"Zahtev za otključavanje RUIM kartice nije uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ERROR" msgid="894358680773257820">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ERROR" msgid="352466878146726991">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ERROR" msgid="7353389721907138671">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ERROR" msgid="2655263155490857920">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_SIM_PUK_ERROR" msgid="6903740900892931310">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ERROR" msgid="5165901670447518687">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ERROR" msgid="2856763216589267623">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ERROR" msgid="817542684437829139">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ERROR" msgid="5178635064113393143">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ERROR" msgid="5391587926974531008">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ERROR" msgid="4895494864493315868">"Otključavanje pomoću PUK-a nije uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_SPN_ERROR" msgid="9017576601595353649">"Zahtev za otključavanje SPN-a nije uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ERROR" msgid="1116993930995545742">"Zahtev za otključavanje SP ekvivalentnog matičnog PLMN-a nije uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_ICCID_ERROR" msgid="7559167306794441462">"Zahtev za otključavanje ICCID-a nije uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_IMPI_ERROR" msgid="2782926139511136588">"Zahtev za otključavanje IMPI-ja nije uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_NS_SP_ERROR" msgid="1890493954453456758">"Zahtev za otključavanje dobavljača usluge podskupa mreže nije uspeo."</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_SUCCESS" msgid="4886243367747126325">"Otključavanje SIM mreže je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_SUCCESS" msgid="4053809277733513987">"Otključavanje podskupa SIM mreže je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_SUCCESS" msgid="8249342930499801740">"Otključavanje dobavljača usluge SIM kartice je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_CORPORATE_SUCCESS" msgid="2339794542560381270">"Otključavanje poslovne SIM kartice je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_SIM_SUCCESS" msgid="6975608174152828954">"Otključavanje SIM kartice je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK1_SUCCESS" msgid="2846699261330463192">"Otključavanje RUIM mreže 1 je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK2_SUCCESS" msgid="5335414726057102801">"Otključavanje RUIM mreže 2 je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_HRPD_SUCCESS" msgid="8868100318474971969">"Otključavanje RUIM hrpd-a je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_SUCCESS" msgid="6020936629725666932">"Zahtev za otključavanje RUIM kartice dobavljača usluge je uspeo."</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_SUCCESS" msgid="6944873647584595489">"Otključavanje poslovne RUIM kartice je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_RUIM_SUCCESS" msgid="2526483514124121988">"Otključavanje RUIM kartice je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_SUCCESS" msgid="7662200333621664621">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_SUCCESS" msgid="2861223407953766632">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_SUCCESS" msgid="5345648571175243272">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_SUCCESS" msgid="3725278343103422466">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_SIM_PUK_SUCCESS" msgid="6998502547560297983">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_SUCCESS" msgid="8555433771162560361">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_SUCCESS" msgid="3555767296933606232">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_SUCCESS" msgid="6778051818199974237">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_SUCCESS" msgid="4080108758498911429">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_SUCCESS" msgid="7873675303000794343">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_SUCCESS" msgid="1763198215069819523">"Otključavanje pomoću PUK-a je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_SPN_SUCCESS" msgid="2053891977727320532">"Otključavanje SPN-a je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_SUCCESS" msgid="8146602361895007345">"Otključavanje SP ekvivalentnog matičnog PLMN-a je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_ICCID_SUCCESS" msgid="8058678548991999545">"Otključavanje ICCID-a je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_IMPI_SUCCESS" msgid="2545608067978550571">"Otključavanje IMPI-ja je uspelo."</string>
- <string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS" msgid="4352382949744625007">"Zahtev za otključavanje dobavljača usluge podskupa mreže je uspeo."</string>
+ <string name="resolver_personal_tab" msgid="2051260504014442073">"Лично"</string>
+ <string name="resolver_work_tab" msgid="2690019516263167035">"Пословно"</string>
+ <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Лични приказ"</string>
+ <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Приказ за посао"</string>
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Блокира ИТ администратор"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Овај садржај не може да се дели помоћу пословних апликација"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Овај садржај не може да се отвара помоћу пословних апликација"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Овај садржај не може да се дели помоћу личних апликација"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Овај садржај не може да се отвара помоћу личних апликација"</string>
+ <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Пословни профил је паузиран"</string>
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Додирните да бисте укључили"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Нема пословних апликација"</string>
+ <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Нема личних апликација"</string>
+ <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"Желите да на личном профилу отворите: <xliff:g id="APP">%s</xliff:g>?"</string>
+ <string name="miniresolver_open_in_work" msgid="4415223793669536559">"Желите да на пословном профилу отворите: <xliff:g id="APP">%s</xliff:g>?"</string>
+ <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Користи лични прегледач"</string>
+ <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Користи пословни прегледач"</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN за откључавање SIM мреже"</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN за откључавање подскупа SIM мреже"</string>
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN за откључавање пословне SIM картице"</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ENTRY" msgid="973059024670737358">"PIN за откључавање добављача услуге SIM картице"</string>
+ <string name="PERSOSUBSTATE_SIM_SIM_ENTRY" msgid="4487435301206073787">"PIN за откључавање SIM картице"</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ENTRY" msgid="768060297218652809">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ENTRY" msgid="7129527319490548930">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ENTRY" msgid="2876126640607573252">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="8952595089930109282">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_SIM_SIM_PUK_ENTRY" msgid="3013902515773728996">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_ENTRY" msgid="2974411408893410289">"PIN за откључавање RUIM мреже 1"</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_ENTRY" msgid="687618528751880721">"PIN за откључавање RUIM мреже 2"</string>
+ <string name="PERSOSUBSTATE_RUIM_HRPD_ENTRY" msgid="6810596579655575381">"PIN за откључавање RUIM hrpd-а"</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_ENTRY" msgid="2715929642540980259">"PIN за откључавање пословне RUIM картице"</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ENTRY" msgid="8557791623303951590">"PIN за откључавање RUIM картице добављача услуге"</string>
+ <string name="PERSOSUBSTATE_RUIM_RUIM_ENTRY" msgid="7382468767274580323">"PIN за откључавање RUIM картице"</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ENTRY" msgid="6730880791104286987">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ENTRY" msgid="6432126539782267026">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ENTRY" msgid="1730510161529488920">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="3369885925003346830">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ENTRY" msgid="9129139686191167829">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ENTRY" msgid="2869929685874615358">"Унесите PUK"</string>
+ <string name="PERSOSUBSTATE_SIM_SPN_ENTRY" msgid="1238663472392741771">"PIN за откључавање SPN-а"</string>
+ <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ENTRY" msgid="3988705848553894358">"PIN за откључавање SP еквивалентног матичног PLMN-а"</string>
+ <string name="PERSOSUBSTATE_SIM_ICCID_ENTRY" msgid="6186770686690993200">"PIN за откључавање ICCID-а"</string>
+ <string name="PERSOSUBSTATE_SIM_IMPI_ENTRY" msgid="7043865376145617024">"PIN за откључавање IMPI-ја"</string>
+ <string name="PERSOSUBSTATE_SIM_NS_SP_ENTRY" msgid="6144227308185112176">"PIN за откључавање добављача услуге подскупа мреже"</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_IN_PROGRESS" msgid="4233355366318061180">"Захтева се откључавање SIM мреже…"</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_IN_PROGRESS" msgid="6742563947637715645">"Захтева се откључавање подскупа SIM мреже…"</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="2033399698172403560">"Захтева се откључавање добављача услуге SIM картице…"</string>
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_IN_PROGRESS" msgid="4795977251920732254">"Захтева се откључавање пословне SIM картице…"</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_IN_PROGRESS" msgid="1090425878157254446">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_IN_PROGRESS" msgid="6476898876518094438">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_IN_PROGRESS" msgid="6006806734293747731">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_IN_PROGRESS" msgid="6546680489620881893">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_SIM_SIM_PUK_IN_PROGRESS" msgid="3506845511000727015">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_SIM_SIM_IN_PROGRESS" msgid="6709169861932992750">"Захтева се откључавање SIM картице…"</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_IN_PROGRESS" msgid="4013870911606478520">"Захтева се откључавање RUIM мреже 1…"</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_IN_PROGRESS" msgid="9032651188219523434">"Захтева се откључавање RUIM мреже 2…"</string>
+ <string name="PERSOSUBSTATE_RUIM_HRPD_IN_PROGRESS" msgid="6584576506344491207">"Захтева се откључавање RUIM hrpd-а…"</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="830981927724888114">"Захтева се откључавање RUIM картице добављача услуге…"</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_IN_PROGRESS" msgid="7851790973098894802">"Захтева се откључавање пословне RUIM картице…"</string>
+ <string name="PERSOSUBSTATE_SIM_SPN_IN_PROGRESS" msgid="1149560739586960121">"Захтева се откључавање SPN-а…"</string>
+ <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_IN_PROGRESS" msgid="5708964693522116025">"Захтева се откључавање SP еквивалентног матичног PLMN-а…"</string>
+ <string name="PERSOSUBSTATE_SIM_ICCID_IN_PROGRESS" msgid="7288103122966483455">"Захтева се откључавање ICCID-а…"</string>
+ <string name="PERSOSUBSTATE_SIM_IMPI_IN_PROGRESS" msgid="4036752174056147753">"Захтева се откључавање IMPI-ја…"</string>
+ <string name="PERSOSUBSTATE_SIM_NS_SP_IN_PROGRESS" msgid="5089536274515338566">"Захтева се откључавање добављача услуге подскупа мреже…"</string>
+ <string name="PERSOSUBSTATE_RUIM_RUIM_IN_PROGRESS" msgid="6737197986936251958">"Захтева се откључавање RUIM картице…"</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_IN_PROGRESS" msgid="5658767775619998623">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_IN_PROGRESS" msgid="665978313257653727">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_IN_PROGRESS" msgid="3857142652251836850">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_IN_PROGRESS" msgid="2695664012344346788">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_IN_PROGRESS" msgid="2695678959963807782">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_IN_PROGRESS" msgid="1230605365926493599">"Захтева се откључавање помоћу PUK-а…"</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_ERROR" msgid="1924844017037151535">"Захтев за откључавање SIM мреже није успео."</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ERROR" msgid="3372797822292089708">"Захтев за откључавање подскупа SIM мреже је успео."</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ERROR" msgid="1878443146720411381">"Захтев за откључавање добављача услуге SIM картице није успео."</string>
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_ERROR" msgid="7664778312218023192">"Захтев за откључавање пословне SIM картице није успео."</string>
+ <string name="PERSOSUBSTATE_SIM_SIM_ERROR" msgid="2472944311643350302">"Захтев за откључавање SIM картице није успео."</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_ERROR" msgid="828089694480999120">"Захтев за откључавање RUIM мреже 1 није успео."</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_ERROR" msgid="17619001007092511">"Захтев за откључавање RUIM мреже 2 није успео."</string>
+ <string name="PERSOSUBSTATE_RUIM_HRPD_ERROR" msgid="807214229604353614">"Захтев за откључавање RUIM hrpd-а није успео."</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_ERROR" msgid="8644184447744175747">"Захтев за откључавање пословне RUIM картице није успео."</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ERROR" msgid="3801002648649640407">"Захтев за откључавање RUIM картице добављача услуге није успео."</string>
+ <string name="PERSOSUBSTATE_RUIM_RUIM_ERROR" msgid="707397021218680753">"Захтев за откључавање RUIM картице није успео."</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ERROR" msgid="894358680773257820">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ERROR" msgid="352466878146726991">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ERROR" msgid="7353389721907138671">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ERROR" msgid="2655263155490857920">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_SIM_SIM_PUK_ERROR" msgid="6903740900892931310">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ERROR" msgid="5165901670447518687">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ERROR" msgid="2856763216589267623">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ERROR" msgid="817542684437829139">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ERROR" msgid="5178635064113393143">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ERROR" msgid="5391587926974531008">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ERROR" msgid="4895494864493315868">"Откључавање помоћу PUK-а није успело."</string>
+ <string name="PERSOSUBSTATE_SIM_SPN_ERROR" msgid="9017576601595353649">"Захтев за откључавање SPN-а није успео."</string>
+ <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ERROR" msgid="1116993930995545742">"Захтев за откључавање SP еквивалентног матичног PLMN-а није успео."</string>
+ <string name="PERSOSUBSTATE_SIM_ICCID_ERROR" msgid="7559167306794441462">"Захтев за откључавање ICCID-а није успео."</string>
+ <string name="PERSOSUBSTATE_SIM_IMPI_ERROR" msgid="2782926139511136588">"Захтев за откључавање IMPI-ја није успео."</string>
+ <string name="PERSOSUBSTATE_SIM_NS_SP_ERROR" msgid="1890493954453456758">"Захтев за откључавање добављача услуге подскупа мреже није успео."</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUCCESS" msgid="4886243367747126325">"Откључавање SIM мреже је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_SUCCESS" msgid="4053809277733513987">"Откључавање подскупа SIM мреже је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_SUCCESS" msgid="8249342930499801740">"Откључавање добављача услуге SIM картице је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_SUCCESS" msgid="2339794542560381270">"Откључавање пословне SIM картице је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_SIM_SUCCESS" msgid="6975608174152828954">"Откључавање SIM картице је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_SUCCESS" msgid="2846699261330463192">"Откључавање RUIM мреже 1 је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_SUCCESS" msgid="5335414726057102801">"Откључавање RUIM мреже 2 је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_HRPD_SUCCESS" msgid="8868100318474971969">"Откључавање RUIM hrpd-а је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_SUCCESS" msgid="6020936629725666932">"Захтев за откључавање RUIM картице добављача услуге је успео."</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_SUCCESS" msgid="6944873647584595489">"Откључавање пословне RUIM картице је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_RUIM_SUCCESS" msgid="2526483514124121988">"Откључавање RUIM картице је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_SUCCESS" msgid="7662200333621664621">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_SUCCESS" msgid="2861223407953766632">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_SUCCESS" msgid="5345648571175243272">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_SUCCESS" msgid="3725278343103422466">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_SIM_PUK_SUCCESS" msgid="6998502547560297983">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_SUCCESS" msgid="8555433771162560361">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_SUCCESS" msgid="3555767296933606232">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_SUCCESS" msgid="6778051818199974237">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_SUCCESS" msgid="4080108758498911429">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_SUCCESS" msgid="7873675303000794343">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_SUCCESS" msgid="1763198215069819523">"Откључавање помоћу PUK-а је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_SPN_SUCCESS" msgid="2053891977727320532">"Откључавање SPN-а је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_SUCCESS" msgid="8146602361895007345">"Откључавање SP еквивалентног матичног PLMN-а је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_ICCID_SUCCESS" msgid="8058678548991999545">"Откључавање ICCID-а је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_IMPI_SUCCESS" msgid="2545608067978550571">"Откључавање IMPI-ја је успело."</string>
+ <string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS" msgid="4352382949744625007">"Захтев за откључавање добављача услуге подскупа мреже је успео."</string>
<string name="config_pdp_reject_dialog_title" msgid="4072057179246785727"></string>
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Nova podešavanja uvećanja"</string>
- <string name="window_magnification_prompt_content" msgid="8159173903032344891">"Sada možete da uvećate deo ekrana"</string>
- <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Podešavanjima"</string>
- <string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
- <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Odblokirajte mikrofon uređaja"</string>
- <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Odblokirajte kameru uređaja"</string>
- <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Za <b><xliff:g id="APP">%s</xliff:g></b> i sve aplikacije i usluge"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Odblokiraj"</string>
- <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string>
- <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
- <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imidž brenda aplikacije"</string>
- <string name="view_and_control_notification_title" msgid="4300765399209912240">"Proverite podešavanja pristupa"</string>
- <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> može da pregleda i kontroliše ekran. Dodirnite da biste pregledali."</string>
- <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Prevedeno."</string>
- <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Poruka je prevedena sa jezika <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> na <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
- <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivnost u pozadini"</string>
- <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Aplikacija vam prazni bateriju"</string>
- <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikacija je i dalje aktivna"</string>
- <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> radi u pozadini. Dodirnite da biste upravljali potrošnjom baterije."</string>
- <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> može da utiče na trajanje baterije. Dodirnite da biste pregledali aktivne aplikacije."</string>
- <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Proverite aktivne aplikacije"</string>
- <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ne može da se pristupi kameri telefona sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
- <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ne može da se pristupi kameri tableta sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
- <string name="vdm_secure_window" msgid="161700398158812314">"Ovom ne možete da pristupate tokom strimovanja. Probajte na telefonu."</string>
- <string name="system_locale_title" msgid="711882686834677268">"Podrazumevani sistemski"</string>
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Нова подешавања увећања"</string>
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"Сада можете да увећате део екрана"</string>
+ <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Укључите у Подешавањима"</string>
+ <string name="dismiss_action" msgid="1728820550388704784">"Одбаци"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Одблокирајте микрофон уређаја"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Одблокирајте камеру уређаја"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"За <b><xliff:g id="APP">%s</xliff:g></b> и све апликације и услуге"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Одблокирај"</string>
+ <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Приватност сензора"</string>
+ <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Икона апликације"</string>
+ <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Имиџ бренда апликације"</string>
+ <string name="view_and_control_notification_title" msgid="4300765399209912240">"Проверите подешавања приступа"</string>
+ <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> може да прегледа и контролише екран. Додирните да бисте прегледали."</string>
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Преведено."</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Порука је преведена са језика <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> на <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
+ <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Активност у позадини"</string>
+ <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Апликација вам празни батерију"</string>
+ <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Апликација је и даље активна"</string>
+ <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"Апликација <xliff:g id="APP">%1$s</xliff:g> ради у позадини. Додирните да бисте управљали потрошњом батерије."</string>
+ <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> може да утиче на трајање батерије. Додирните да бисте прегледали активне апликације."</string>
+ <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверите активне апликације"</string>
+ <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се приступи камери телефона са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string>
+ <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се приступи камери таблета са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string>
+ <string name="vdm_secure_window" msgid="161700398158812314">"Овом не можете да приступате током стримовања. Пробајте на телефону."</string>
+ <string name="system_locale_title" msgid="711882686834677268">"Подразумевани системски"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index c527e59..2d8f21d 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1974,7 +1974,7 @@
<string name="pin_specific_target" msgid="7824671240625957415">"Замацаваць праграму \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string>
<string name="unpin_target" msgid="3963318576590204447">"Адмацаваць"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"Адмацаваць праграму \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string>
- <string name="app_info" msgid="6113278084877079851">"Інфармацыя пра праграму"</string>
+ <string name="app_info" msgid="6113278084877079851">"Звесткі аб праграме"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Ідзе запуск дэманстрацыі…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"Ідзе скід налад прылады…"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 0ec4f1d..40b265a 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1167,8 +1167,8 @@
<string name="no" msgid="5122037903299899715">"Annuler"</string>
<string name="dialog_alert_title" msgid="651856561974090712">"Attention"</string>
<string name="loading" msgid="3138021523725055037">"Chargement en cours..."</string>
- <string name="capital_on" msgid="2770685323900821829">"OUI"</string>
- <string name="capital_off" msgid="7443704171014626777">"NON"</string>
+ <string name="capital_on" msgid="2770685323900821829">"ACTIVÉ"</string>
+ <string name="capital_off" msgid="7443704171014626777">"DÉSACTIVÉ"</string>
<string name="checked" msgid="9179896827054513119">"coché"</string>
<string name="not_checked" msgid="7972320087569023342">"non coché"</string>
<string name="selected" msgid="6614607926197755875">"sélectionné"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 38a7c7b..b02345a 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -626,15 +626,15 @@
</string-array>
<string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Terjadi error. Coba lagi."</string>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon sidik jari"</string>
- <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Face Unlock"</string>
- <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Masalah pada Face Unlock"</string>
+ <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Buka dengan Wajah"</string>
+ <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Masalah pada Buka dengan Wajah"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Ketuk untuk menghapus model wajah, lalu tambahkan wajah Anda lagi"</string>
- <string name="face_setup_notification_title" msgid="8843461561970741790">"Siapkan Face Unlock"</string>
+ <string name="face_setup_notification_title" msgid="8843461561970741790">"Siapkan Buka dengan Wajah"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"Buka kunci ponsel dengan melihat ke ponsel"</string>
- <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Untuk menggunakan Face Unlock, aktifkan "<b>"Akses kamera"</b>" di Setelan > Privasi"</string>
+ <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Untuk menggunakan Buka dengan Wajah, aktifkan "<b>"Akses kamera"</b>" di Setelan > Privasi"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Siapkan lebih banyak cara untuk membuka kunci"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Ketuk untuk menambahkan sidik jari"</string>
- <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingerprint Unlock"</string>
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Buka dengan Sidik Jari"</string>
<string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Tidak dapat menggunakan sensor sidik jari"</string>
<string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Kunjungi penyedia reparasi."</string>
<string name="face_acquired_insufficient" msgid="6889245852748492218">"Tidak dapat membuat model wajah Anda. Coba lagi."</string>
@@ -667,19 +667,19 @@
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Tidak dapat memverifikasi wajah. Hardware tidak tersedia."</string>
- <string name="face_error_timeout" msgid="2598544068593889762">"Coba Face Unlock lagi"</string>
+ <string name="face_error_timeout" msgid="2598544068593889762">"Coba Buka dengan Wajah lagi"</string>
<string name="face_error_no_space" msgid="5649264057026021723">"Tidak dapat menyimpan data wajah. Hapus dahulu data lama."</string>
<string name="face_error_canceled" msgid="2164434737103802131">"Pemrosesan wajah dibatalkan."</string>
- <string name="face_error_user_canceled" msgid="5766472033202928373">"Face Unlock dibatalkan oleh pengguna"</string>
+ <string name="face_error_user_canceled" msgid="5766472033202928373">"Buka dengan Wajah dibatalkan oleh pengguna"</string>
<string name="face_error_lockout" msgid="7864408714994529437">"Terlalu banyak percobaan. Coba lagi nanti."</string>
- <string name="face_error_lockout_permanent" msgid="3277134834042995260">"Terlalu banyak upaya gagal. Face Unlock dinonaktifkan."</string>
+ <string name="face_error_lockout_permanent" msgid="3277134834042995260">"Terlalu banyak upaya gagal. Buka dengan Wajah dinonaktifkan."</string>
<string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Terlalu banyak upaya gagal. Masukkan kunci layar."</string>
<string name="face_error_unable_to_process" msgid="5723292697366130070">"Tidak dapat memverifikasi wajah. Coba lagi."</string>
- <string name="face_error_not_enrolled" msgid="1134739108536328412">"Anda belum menyiapkan Face Unlock"</string>
- <string name="face_error_hw_not_present" msgid="7940978724978763011">"Face Unlock tidak didukung di perangkat ini"</string>
+ <string name="face_error_not_enrolled" msgid="1134739108536328412">"Anda belum menyiapkan Buka dengan Wajah"</string>
+ <string name="face_error_hw_not_present" msgid="7940978724978763011">"Buka dengan Wajah tidak didukung di perangkat ini"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor dinonaktifkan untuk sementara."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> wajah"</string>
- <string name="face_app_setting_name" msgid="5854024256907828015">"Gunakan Face Unlock"</string>
+ <string name="face_app_setting_name" msgid="5854024256907828015">"Gunakan Buka dengan Wajah"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gunakan face lock atau kunci layar"</string>
<string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Gunakan wajah untuk melanjutkan"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Gunakan face lock atau kunci layar untuk melanjutkan"</string>
@@ -928,7 +928,7 @@
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Coba lagi"</string>
<string name="lockscreen_password_wrong" msgid="8605355913868947490">"Coba lagi"</string>
<string name="lockscreen_storage_locked" msgid="634993789186443380">"Membuka kunci untuk semua fitur dan data"</string>
- <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Percobaan Face Unlock melebihi batas maksimum"</string>
+ <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Percobaan Buka dengan Wajah melebihi batas maksimum"</string>
<string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"Tidak ada kartu SIM"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"Tidak ada kartu SIM dalam tablet."</string>
<string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"Tidak ada kartu SIM di perangkat Android TV."</string>
@@ -998,7 +998,7 @@
<string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Luaskan area buka kunci."</string>
<string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Buka kunci dengan menggeser."</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Buka kunci dengan pola."</string>
- <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Face Unlock."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Buka dengan Wajah."</string>
<string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Buka kunci dengan PIN."</string>
<string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"PIN SIM terbuka."</string>
<string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"PUK SIM terbuka."</string>
diff --git a/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml b/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml
index 7c0fc70..b003fe0 100644
--- a/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc001-mnc01-b+sr+Latn/strings.xml
@@ -20,5 +20,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_illegal_me" msgid="6819499009131365312">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_illegal_me" msgid="6819499009131365312">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml
index 81b9be8..b0a8ae5 100644
--- a/core/res/res/values-mcc310-mnc030-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-b+sr+Latn/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="mmcc_imsi_unknown_in_hlr" msgid="656054059094417927">"SIM kartica nije podešena MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="1782569305985001089">"SIM kartica nije dozvoljena MM#3"</string>
- <string name="mmcc_illegal_me" msgid="8246632898824321280">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="656054059094417927">"SIM картица није подешена MM#2"</string>
+ <string name="mmcc_illegal_ms" msgid="1782569305985001089">"SIM картица није дозвољена MM#3"</string>
+ <string name="mmcc_illegal_me" msgid="8246632898824321280">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml
index d066eb62..c70f4b7 100644
--- a/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc150-b+sr+Latn/strings.xml
@@ -20,5 +20,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_illegal_me" msgid="8004509200390992737">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_illegal_me" msgid="8004509200390992737">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml
index ff89bab..011a40d 100644
--- a/core/res/res/values-mcc310-mnc170-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-b+sr+Latn/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="mmcc_imsi_unknown_in_hlr" msgid="5424518490295341205">"SIM kartica nije podešena MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="3527626511418944853">"SIM kartica nije dozvoljena MM#3"</string>
- <string name="mmcc_illegal_me" msgid="3948912590657398489">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="5424518490295341205">"SIM картица није подешена MM#2"</string>
+ <string name="mmcc_illegal_ms" msgid="3527626511418944853">"SIM картица није дозвољена MM#3"</string>
+ <string name="mmcc_illegal_me" msgid="3948912590657398489">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml
index faf51d3..9b0dcf1 100644
--- a/core/res/res/values-mcc310-mnc280-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-b+sr+Latn/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="mmcc_imsi_unknown_in_hlr" msgid="1070849538022865416">"SIM kartica nije podešena MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="499832197298480670">"SIM kartica nije dozvoljena MM#3"</string>
- <string name="mmcc_illegal_me" msgid="2346111479504469688">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="1070849538022865416">"SIM картица није подешена MM#2"</string>
+ <string name="mmcc_illegal_ms" msgid="499832197298480670">"SIM картица није дозвољена MM#3"</string>
+ <string name="mmcc_illegal_me" msgid="2346111479504469688">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc380-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc380-b+sr+Latn/strings.xml
index e348095..256ad83b 100644
--- a/core/res/res/values-mcc310-mnc380-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc380-b+sr+Latn/strings.xml
@@ -20,6 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_imsi_unknown_in_hlr" msgid="6178029798083341927">"SIM kartica nije podešena MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="6084322234976891423">"SIM kartica nije dozvoljena MM#3"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="6178029798083341927">"SIM картица није подешена MM#2"</string>
+ <string name="mmcc_illegal_ms" msgid="6084322234976891423">"SIM картица није дозвољена MM#3"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml
index 940507b..e8835d2 100644
--- a/core/res/res/values-mcc310-mnc410-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-b+sr+Latn/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="mmcc_imsi_unknown_in_hlr" msgid="8861901652350883183">"SIM kartica nije podešena MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="2604694337529846283">"SIM kartica nije dozvoljena MM#3"</string>
- <string name="mmcc_illegal_me" msgid="3099618295079374317">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="8861901652350883183">"SIM картица није подешена MM#2"</string>
+ <string name="mmcc_illegal_ms" msgid="2604694337529846283">"SIM картица није дозвољена MM#3"</string>
+ <string name="mmcc_illegal_me" msgid="3099618295079374317">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml
index 2a0e83c..bacde69 100644
--- a/core/res/res/values-mcc310-mnc560-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-b+sr+Latn/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="mmcc_imsi_unknown_in_hlr" msgid="3526528316378889524">"SIM kartica nije podešena MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="4618730283812066268">"SIM kartica nije dozvoljena MM#3"</string>
- <string name="mmcc_illegal_me" msgid="8522039751358990401">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="3526528316378889524">"SIM картица није подешена MM#2"</string>
+ <string name="mmcc_illegal_ms" msgid="4618730283812066268">"SIM картица није дозвољена MM#3"</string>
+ <string name="mmcc_illegal_me" msgid="8522039751358990401">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml
index cdf92ca..9005aaf 100644
--- a/core/res/res/values-mcc310-mnc950-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-b+sr+Latn/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="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"SIM kartica nije podešena MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="7801541624846497489">"SIM kartica nije dozvoljena MM#3"</string>
- <string name="mmcc_illegal_me" msgid="7066936962628406316">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"SIM картица није подешена MM#2"</string>
+ <string name="mmcc_illegal_ms" msgid="7801541624846497489">"SIM картица није дозвољена MM#3"</string>
+ <string name="mmcc_illegal_me" msgid="7066936962628406316">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml b/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml
index 6cbc6ee..baec8cd 100644
--- a/core/res/res/values-mcc311-mnc180-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-b+sr+Latn/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="mmcc_imsi_unknown_in_hlr" msgid="604133804161351810">"SIM kartica nije podešena MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="4073997279280371621">"SIM kartica nije dozvoljena MM#3"</string>
- <string name="mmcc_illegal_me" msgid="4936539345546223576">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="604133804161351810">"SIM картица није подешена MM#2"</string>
+ <string name="mmcc_illegal_ms" msgid="4073997279280371621">"SIM картица није дозвољена MM#3"</string>
+ <string name="mmcc_illegal_me" msgid="4936539345546223576">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml b/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml
index d9b6793..6c738a2 100644
--- a/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc312-mnc670-b+sr+Latn/strings.xml
@@ -20,5 +20,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_illegal_me" msgid="8271599016773350087">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_illegal_me" msgid="8271599016773350087">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml b/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml
index 4740afd..1ff6057 100644
--- a/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc313-mnc100-b+sr+Latn/strings.xml
@@ -20,5 +20,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mmcc_illegal_me" msgid="8297733805803070310">"Telefon nije dozvoljen MM#6"</string>
+ <string name="mmcc_illegal_me" msgid="8297733805803070310">"Телефон није дозвољен MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc334-mnc020-b+sr+Latn/strings.xml b/core/res/res/values-mcc334-mnc020-b+sr+Latn/strings.xml
index b27e485..ddf0ce1 100644
--- a/core/res/res/values-mcc334-mnc020-b+sr+Latn/strings.xml
+++ b/core/res/res/values-mcc334-mnc020-b+sr+Latn/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="config_pdp_reject_dialog_title" msgid="41208110171880430"></string>
- <string name="config_pdp_reject_user_authentication_failed" msgid="4683454131283459978">"POTVRDA IDENTITETA NIJE USPELA -29-"</string>
- <string name="config_pdp_reject_service_not_subscribed" msgid="9021140729932308119">"NISTE PRETPLAĆENI NA USLUGU -33-"</string>
- <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="3838388706348367865">"Nije dozvoljeno više PDN veza za određeni APN -55-"</string>
+ <string name="config_pdp_reject_user_authentication_failed" msgid="4683454131283459978">"ПОТВРДА ИДЕНТИТЕТА НИЈЕ УСПЕЛА -29-"</string>
+ <string name="config_pdp_reject_service_not_subscribed" msgid="9021140729932308119">"НИСТЕ ПРЕТПЛАЋЕНИ НА УСЛУГУ -33-"</string>
+ <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="3838388706348367865">"Није дозвољено више PDN веза за одређени APN -55-"</string>
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 6b88f8e..42a477b 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -897,7 +897,7 @@
<string name="relationTypeFriend" msgid="3192092625893980574">"Amigo(a)"</string>
<string name="relationTypeManager" msgid="2272860813153171857">"Gerente"</string>
<string name="relationTypeMother" msgid="2331762740982699460">"Mãe"</string>
- <string name="relationTypeParent" msgid="4177920938333039882">"Pai/Mãe"</string>
+ <string name="relationTypeParent" msgid="4177920938333039882">"familiar responsável"</string>
<string name="relationTypePartner" msgid="4018017075116766194">"Parceiro"</string>
<string name="relationTypeReferredBy" msgid="5285082289602849400">"Indicado por"</string>
<string name="relationTypeRelative" msgid="3396498519818009134">"Parente"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 6b88f8e..42a477b 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -897,7 +897,7 @@
<string name="relationTypeFriend" msgid="3192092625893980574">"Amigo(a)"</string>
<string name="relationTypeManager" msgid="2272860813153171857">"Gerente"</string>
<string name="relationTypeMother" msgid="2331762740982699460">"Mãe"</string>
- <string name="relationTypeParent" msgid="4177920938333039882">"Pai/Mãe"</string>
+ <string name="relationTypeParent" msgid="4177920938333039882">"familiar responsável"</string>
<string name="relationTypePartner" msgid="4018017075116766194">"Parceiro"</string>
<string name="relationTypeReferredBy" msgid="5285082289602849400">"Indicado por"</string>
<string name="relationTypeRelative" msgid="3396498519818009134">"Parente"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index bfb7a38..01e57e1 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -993,7 +993,7 @@
<string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Výber používateľa"</string>
<string name="keyguard_accessibility_status" msgid="6792745049712397237">"Stav"</string>
<string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Fotoaparát"</string>
- <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Ovládacie prvky médií"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Ovládanie médií"</string>
<string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Zmena usporiadania miniaplikácií sa začala."</string>
<string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Zmena usporiadania miniaplikácií sa skončila."</string>
<string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Miniaplikácia <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> bola odstránená."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 8647c5c..1a5e13b 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -364,7 +364,7 @@
<string name="permdesc_receiveMms" msgid="958102423732219710">"MMS మెసేజ్లను స్వీకరించడానికి, ప్రాసెస్ చేయడానికి యాప్ను అనుమతిస్తుంది. మీ డివైజ్కు వచ్చిన మెసేజ్లను మీకు చూపకుండానే యాప్ పర్యవేక్షించగలదని లేదా తొలగించగలదని దీని అర్థం."</string>
<string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"సెల్ ప్రసార మెసేజ్లను ఫార్వర్డ్ చేయడం"</string>
<string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"సెల్ ప్రసార మెసేజ్లను స్వీకరించినప్పుడు, వాటిని ఫార్వర్డ్ చేయడానికి సెల్ ప్రసార మాడ్యూల్కు కట్టుబడి ఉండేందుకు యాప్ను అనుమతిస్తుంది. ఎమర్జెన్సీ పరిస్థితుల గురించి మిమ్మల్ని హెచ్చరించడానికి కొన్ని లొకేషన్లలో సెల్ ప్రసార అలర్ట్లు డెలివరీ చేయబడతాయి. ఎమర్జెన్సీ సెల్ ప్రసార అలర్ట్ను స్వీకరించినప్పుడు హానికరమైన యాప్లు మీ పరికరం పనితీరుకు లేదా నిర్వహణకు ఆటంకం కలిగించే అవకాశం ఉంది."</string>
- <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"కొనసాగుతున్న కాల్స్ను మేనేజ్ చేయి"</string>
+ <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"కొనసాగుతున్న కాల్స్ను మేనేజ్ చేయండి"</string>
<string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"మీ పరికరంలో కొనసాగుతున్న కాల్స్ను చూడటానికి అలాగే వాటిని కంట్రోల్ చేయడానికి ఒక యాప్కు అనుమతిస్తోంది."</string>
<string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"సెల్ ప్రసార మెసేజ్లను చదవడం"</string>
<string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"మీ పరికరం స్వీకరించిన సెల్ ప్రసార మెసేజ్లను చదవడానికి యాప్ను అనుమతిస్తుంది. ఎమర్జెన్సీ పరిస్థితుల గురించి మిమ్మల్ని హెచ్చరించడానికి కొన్ని లొకేషన్లలో సెల్ ప్రసార అలర్ట్లు డెలివరీ చేయబడతాయి. ఎమర్జెన్సీ సెల్ ప్రసార అలర్ట్ను స్వీకరించినప్పుడు హానికరమైన యాప్లు మీ పరికరం పనితీరుకు లేదా నిర్వహణకు ఆటంకం కలిగించే అవకాశం ఉంది."</string>
@@ -1145,11 +1145,11 @@
<string name="delete" msgid="1514113991712129054">"తొలగించండి"</string>
<string name="copyUrl" msgid="6229645005987260230">"URLని కాపీ చేయి"</string>
<string name="selectTextMode" msgid="3225108910999318778">"వచనాన్ని ఎంచుకోండి"</string>
- <string name="undo" msgid="3175318090002654673">"చర్య రద్దు చేయి"</string>
+ <string name="undo" msgid="3175318090002654673">"చర్య రద్దు చేయండి"</string>
<string name="redo" msgid="7231448494008532233">"చర్యను రిపీట్ చేయి"</string>
<string name="autofill" msgid="511224882647795296">"ఆటోఫిల్"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"వచన ఎంపిక"</string>
- <string name="addToDictionary" msgid="8041821113480950096">"నిఘంటువుకు జోడించు"</string>
+ <string name="addToDictionary" msgid="8041821113480950096">"నిఘంటువుకు జోడించండి"</string>
<string name="deleteText" msgid="4200807474529938112">"తొలగించండి"</string>
<string name="inputMethod" msgid="1784759500516314751">"ఇన్పుట్ పద్ధతి"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"వచనానికి సంబంధించిన చర్యలు"</string>
@@ -1425,7 +1425,7 @@
<string name="ext_media_unmounting_notification_title" msgid="4147986383917892162">"<xliff:g id="NAME">%s</xliff:g>ని తొలగిస్తోంది"</string>
<string name="ext_media_unmounting_notification_message" msgid="5717036261538754203">"తీసివేయవద్దు"</string>
<string name="ext_media_init_action" msgid="2312974060585056709">"సెటప్ చేయండి"</string>
- <string name="ext_media_unmount_action" msgid="966992232088442745">"తొలగించు"</string>
+ <string name="ext_media_unmount_action" msgid="966992232088442745">"తొలగించండి"</string>
<string name="ext_media_browse_action" msgid="344865351947079139">"విశ్లేషించు"</string>
<string name="ext_media_seamless_action" msgid="8837030226009268080">"అవుట్పుట్ మార్చండి"</string>
<string name="ext_media_missing_title" msgid="3209472091220515046">"<xliff:g id="NAME">%s</xliff:g> కనుగొనబడటం లేదు"</string>
@@ -1525,7 +1525,7 @@
<string name="gpsVerifNo" msgid="1671201856091564741">"కాదు"</string>
<string name="sync_too_many_deletes" msgid="6999440774578705300">"తొలగింపు పరిమితి మించిపోయింది"</string>
<string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, ఖాతా <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="5657871730315579051">"అంశాలను తొలగించు"</string>
+ <string name="sync_really_delete" msgid="5657871730315579051">"అంశాలను తొలగించండి"</string>
<string name="sync_undo_deletes" msgid="5786033331266418896">"తొలగింపులను చర్య రద్దు చేయండి"</string>
<string name="sync_do_nothing" msgid="4528734662446469646">"ఇప్పటికీ ఏమీ చేయవద్దు"</string>
<string name="choose_account_label" msgid="5557833752759831548">"ఖాతాను ఎంచుకోండి"</string>
@@ -1699,7 +1699,7 @@
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"యాక్సెసిబిలిటీ బటన్తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"వాల్యూమ్ కీ షార్ట్కట్తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ఆఫ్ చేయబడింది"</string>
- <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"షార్ట్కట్లను ఎడిట్ చేయి"</string>
+ <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"షార్ట్కట్లను ఎడిట్ చేయండి"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"పూర్తయింది"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"షార్ట్కట్ను ఆఫ్ చేయి"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"షార్ట్కట్ను ఉపయోగించు"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bbbb79c..22f4298 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4789,11 +4789,11 @@
<integer name="config_defaultPeakRefreshRate">0</integer>
<!-- The display uses different gamma curves for different refresh rates. It's hard for panel
- vendor to tune the curves to have exact same brightness for different refresh rate. So
+ vendors to tune the curves to have exact same brightness for different refresh rate. So
flicker could be observed at switch time. The issue is worse at the gamma lower end.
In addition, human eyes are more sensitive to the flicker at darker environment.
To prevent flicker, we only support higher refresh rates if the display brightness is above
- a threshold. And the darker environment could have higher threshold.
+ a threshold.
For example, no higher refresh rate if
display brightness <= disp0 && ambient brightness <= amb0
|| display brightness <= disp1 && ambient brightness <= amb1 -->
@@ -4815,13 +4815,12 @@
<integer name="config_defaultRefreshRateInZone">0</integer>
<!-- The display uses different gamma curves for different refresh rates. It's hard for panel
- vendor to tune the curves to have exact same brightness for different refresh rate. So
+ vendors to tune the curves to have exact same brightness for different refresh rate. So
flicker could be observed at switch time. The issue can be observed on the screen with
even full white content at the high brightness. To prevent flickering, we support fixed
refresh rates if the display and ambient brightness are equal to or above the provided
thresholds. You can define multiple threshold levels as higher brightness environments
- may have lower display brightness requirements for the flickering is visible. And the
- high brightness environment could have higher threshold.
+ may have lower display brightness requirements for the flickering is visible.
For example, fixed refresh rate if
display brightness >= disp0 && ambient brightness >= amb0
|| display brightness >= disp1 && ambient brightness >= amb1 -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b0f6ae6..ba274a7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2331,6 +2331,7 @@
<java-symbol type="drawable" name="scrubber_control_selector_holo" />
<java-symbol type="drawable" name="scrubber_progress_horizontal_holo_dark" />
<java-symbol type="drawable" name="progress_small_material" />
+ <java-symbol type="drawable" name="ic_chevron_end" />
<java-symbol type="string" name="chooseUsbActivity" />
<java-symbol type="string" name="ext_media_badremoval_notification_message" />
<java-symbol type="string" name="ext_media_badremoval_notification_title" />
diff --git a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
index e384e69..d1f0b5e 100644
--- a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
@@ -23,36 +23,53 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import android.provider.DeviceConfig;
+import android.util.Log;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.google.common.truth.Expect;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.time.Duration;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class LatencyTrackerTest {
+ private static final String TAG = LatencyTrackerTest.class.getSimpleName();
private static final String ENUM_NAME_PREFIX = "UIACTION_LATENCY_REPORTED__ACTION__";
+ private static final String ACTION_ENABLE_SUFFIX = "_enable";
+ private static final Duration TEST_TIMEOUT = Duration.ofMillis(500);
@Rule
public final Expect mExpect = Expect.create();
+ @Before
+ public void setUp() {
+ DeviceConfig.deleteProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ LatencyTracker.SETTINGS_ENABLED_KEY);
+ getAllActions().forEach(action -> {
+ DeviceConfig.deleteProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ action.getName().toLowerCase() + ACTION_ENABLE_SUFFIX);
+ });
+ }
+
@Test
public void testCujsMapToEnumsCorrectly() {
- List<Field> actions = Arrays.stream(LatencyTracker.class.getDeclaredFields())
- .filter(f -> f.getName().startsWith("ACTION_")
- && Modifier.isStatic(f.getModifiers())
- && f.getType() == int.class)
- .collect(Collectors.toList());
-
+ List<Field> actions = getAllActions();
Map<Integer, String> enumsMap = Arrays.stream(FrameworkStatsLog.class.getDeclaredFields())
.filter(f -> f.getName().startsWith(ENUM_NAME_PREFIX)
&& Modifier.isStatic(f.getModifiers())
@@ -84,13 +101,7 @@
@Test
public void testCujTypeEnumCorrectlyDefined() throws Exception {
- List<Field> cujEnumFields =
- Arrays.stream(LatencyTracker.class.getDeclaredFields())
- .filter(field -> field.getName().startsWith("ACTION_")
- && Modifier.isStatic(field.getModifiers())
- && field.getType() == int.class)
- .collect(Collectors.toList());
-
+ List<Field> cujEnumFields = getAllActions();
HashSet<Integer> allValues = new HashSet<>();
for (Field field : cujEnumFields) {
int fieldValue = field.getInt(null);
@@ -106,6 +117,95 @@
}
}
+ @Test
+ public void testIsEnabled_globalEnabled() {
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ LatencyTracker.SETTINGS_ENABLED_KEY, "true", false);
+ LatencyTracker latencyTracker = new LatencyTracker();
+ waitForLatencyTrackerToUpdateProperties(latencyTracker);
+ assertThat(latencyTracker.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void testIsEnabled_globalDisabled() {
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ LatencyTracker.SETTINGS_ENABLED_KEY, "false", false);
+ LatencyTracker latencyTracker = new LatencyTracker();
+ waitForLatencyTrackerToUpdateProperties(latencyTracker);
+ assertThat(latencyTracker.isEnabled()).isFalse();
+ }
+
+ @Test
+ public void testIsEnabledAction_useGlobalValueWhenActionEnableIsNotSet() {
+ LatencyTracker latencyTracker = new LatencyTracker();
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ Log.i(TAG, "setting property=" + LatencyTracker.SETTINGS_ENABLED_KEY + ", value=true");
+ latencyTracker.mDeviceConfigPropertiesUpdated.close();
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ LatencyTracker.SETTINGS_ENABLED_KEY, "true", false);
+ waitForLatencyTrackerToUpdateProperties(latencyTracker);
+ assertThat(
+ latencyTracker.isEnabled(action)).isTrue();
+
+ Log.i(TAG, "setting property=" + LatencyTracker.SETTINGS_ENABLED_KEY
+ + ", value=false");
+ latencyTracker.mDeviceConfigPropertiesUpdated.close();
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ LatencyTracker.SETTINGS_ENABLED_KEY, "false", false);
+ waitForLatencyTrackerToUpdateProperties(latencyTracker);
+ assertThat(latencyTracker.isEnabled(action)).isFalse();
+ }
+
+ @Test
+ public void testIsEnabledAction_actionPropertyOverridesGlobalProperty()
+ throws DeviceConfig.BadConfigException {
+ LatencyTracker latencyTracker = new LatencyTracker();
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ String actionEnableProperty = "action_show_voice_interaction" + ACTION_ENABLE_SUFFIX;
+ Log.i(TAG, "setting property=" + actionEnableProperty + ", value=true");
+
+ latencyTracker.mDeviceConfigPropertiesUpdated.close();
+ Map<String, String> properties = new HashMap<String, String>() {{
+ put(LatencyTracker.SETTINGS_ENABLED_KEY, "false");
+ put(actionEnableProperty, "true");
+ }};
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ properties));
+ waitForLatencyTrackerToUpdateProperties(latencyTracker);
+ assertThat(latencyTracker.isEnabled(action)).isTrue();
+
+ latencyTracker.mDeviceConfigPropertiesUpdated.close();
+ Log.i(TAG, "setting property=" + actionEnableProperty + ", value=false");
+ properties.put(LatencyTracker.SETTINGS_ENABLED_KEY, "true");
+ properties.put(actionEnableProperty, "false");
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ properties));
+ waitForLatencyTrackerToUpdateProperties(latencyTracker);
+ assertThat(latencyTracker.isEnabled(action)).isFalse();
+ }
+
+ private void waitForLatencyTrackerToUpdateProperties(LatencyTracker latencyTracker) {
+ try {
+ Thread.sleep(TEST_TIMEOUT.toMillis());
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ assertThat(latencyTracker.mDeviceConfigPropertiesUpdated.block(
+ TEST_TIMEOUT.toMillis())).isTrue();
+ }
+
+ private List<Field> getAllActions() {
+ return Arrays.stream(LatencyTracker.class.getDeclaredFields())
+ .filter(field -> field.getName().startsWith("ACTION_")
+ && Modifier.isStatic(field.getModifiers())
+ && field.getType() == int.class)
+ .collect(Collectors.toList());
+ }
+
private int getIntFieldChecked(Field field) {
try {
return field.getInt(null);
diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
index 4679a9e..0b70199 100644
--- a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
@@ -19,6 +19,9 @@
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
@@ -37,6 +40,7 @@
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.UserInfo;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.UserManager;
import android.provider.Settings;
@@ -233,6 +237,45 @@
ComponentName.unflattenFromString("com.test/.TestAgent"));
}
+ @Test
+ public void isBiometricAllowedForUser_afterTrustagentExpired_returnsTrue()
+ throws RemoteException {
+ TestStrongAuthTracker tracker = createStrongAuthTracker();
+ tracker.changeStrongAuth(SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED);
+
+ assertTrue(tracker.isBiometricAllowedForUser(
+ /* isStrongBiometric = */ true,
+ DEMO_USER_ID));
+ }
+
+ @Test
+ public void isBiometricAllowedForUser_afterLockout_returnsFalse()
+ throws RemoteException {
+ TestStrongAuthTracker tracker = createStrongAuthTracker();
+ tracker.changeStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT);
+
+ assertFalse(tracker.isBiometricAllowedForUser(
+ /* isStrongBiometric = */ true,
+ DEMO_USER_ID));
+ }
+
+
+ private TestStrongAuthTracker createStrongAuthTracker() {
+ final Context context = new ContextWrapper(InstrumentationRegistry.getTargetContext());
+ return new TestStrongAuthTracker(context, Looper.getMainLooper());
+ }
+
+ private static class TestStrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
+
+ TestStrongAuthTracker(Context context, Looper looper) {
+ super(context, looper);
+ }
+
+ public void changeStrongAuth(@StrongAuthFlags int strongAuthFlags) {
+ handleStrongAuthRequiredChanged(strongAuthFlags, DEMO_USER_ID);
+ }
+ }
+
private ILockSettings createTestLockSettings() {
final Context context = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
mLockPatternUtils = spy(new LockPatternUtils(context));
diff --git a/data/etc/com.android.launcher3.xml b/data/etc/com.android.launcher3.xml
index 36a5134..5616d1d 100644
--- a/data/etc/com.android.launcher3.xml
+++ b/data/etc/com.android.launcher3.xml
@@ -25,5 +25,6 @@
<permission name="android.permission.START_TASKS_FROM_RECENTS"/>
<permission name="android.permission.STATUS_BAR"/>
<permission name="android.permission.STOP_APP_SWITCHES"/>
+ <permission name="android.permission.ACCESS_SHORTCUTS"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index a4a38c7..86c8097 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -3871,12 +3871,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/TaskDisplayArea.java"
},
- "1648338379": {
- "message": "Display id=%d is ignoring all orientation requests, return %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_ORIENTATION",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"1653025361": {
"message": "Register task fragment organizer=%s uid=%d pid=%d",
"level": "VERBOSE",
@@ -4117,6 +4111,12 @@
"group": "WM_DEBUG_WINDOW_ORGANIZER",
"at": "com\/android\/server\/wm\/DisplayAreaPolicyBuilder.java"
},
+ "1877863087": {
+ "message": "Display id=%d is ignoring orientation request for %d, return %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"1878927091": {
"message": "prepareSurface: No changes in animation for %s",
"level": "VERBOSE",
diff --git a/data/keyboards/Vendor_18d1_Product_4f80.kl b/data/keyboards/Vendor_18d1_Product_4f80.kl
new file mode 100644
index 0000000..42a6925
--- /dev/null
+++ b/data/keyboards/Vendor_18d1_Product_4f80.kl
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Android Stylus
+#
+
+# Temporarily map the key reported by the stylus to an
+# arbitrary keycode for testing and development.
+key 0x242 VIDEO_APP_1
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index cc2bb63..0bdf98c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -155,6 +155,7 @@
* Adds the data to the storeFeaturesConsumer when the data is ready.
* @param storeFeaturesConsumer a consumer to collect the data when it is first available.
*/
+ @Override
public void getData(Consumer<List<CommonFoldingFeature>> storeFeaturesConsumer) {
mRawFoldSupplier.getData((String displayFeaturesString) -> {
if (TextUtils.isEmpty(displayFeaturesString)) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index d3dc05f..1af1313 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -108,6 +108,7 @@
// Currently applied split configuration.
@GuardedBy("mLock")
private final List<EmbeddingRule> mSplitRules = new ArrayList<>();
+
/**
* A developer-defined {@link SplitAttributes} calculator to compute the current
* {@link SplitAttributes} with the current device and window states.
@@ -125,6 +126,7 @@
@GuardedBy("mLock")
@Nullable
private SplitAttributesCalculator mSplitAttributesCalculator;
+
/**
* Map from Task id to {@link TaskContainer} which contains all TaskFragment and split pair info
* below it.
@@ -230,6 +232,8 @@
}
@NonNull
+ @GuardedBy("mLock")
+ @VisibleForTesting
List<EmbeddingRule> getSplitRules() {
return mSplitRules;
}
@@ -246,7 +250,7 @@
}
/**
- * Clears the listener set in {@link SplitController#setSplitInfoListener}.
+ * Clears the listener set in {@link SplitController#setSplitInfoCallback(Consumer)}.
*/
@Override
public void clearSplitInfoCallback() {
@@ -425,12 +429,8 @@
if (container != null) {
// Cleanup if the TaskFragment vanished is not requested by the organizer.
removeContainer(container);
- // Make sure the top container is updated.
- final TaskFragmentContainer newTopContainer = getTopActiveContainer(
- container.getTaskId());
- if (newTopContainer != null) {
- updateContainer(wct, newTopContainer);
- }
+ // Make sure the containers in the Task are up-to-date.
+ updateContainersInTaskIfVisible(wct, container.getTaskId());
}
cleanupTaskFragment(taskFragmentInfo.getFragmentToken());
}
@@ -470,6 +470,15 @@
updateContainersInTask(wct, taskContainer);
}
+ @GuardedBy("mLock")
+ void updateContainersInTaskIfVisible(@NonNull WindowContainerTransaction wct, int taskId) {
+ final TaskContainer taskContainer = getTaskContainer(taskId);
+ if (taskContainer != null && taskContainer.isVisible()) {
+ updateContainersInTask(wct, taskContainer);
+ }
+ }
+
+ @GuardedBy("mLock")
private void updateContainersInTask(@NonNull WindowContainerTransaction wct,
@NonNull TaskContainer taskContainer) {
// Update all TaskFragments in the Task. Make a copy of the list since some may be
@@ -753,6 +762,7 @@
/**
* Places the given activity to the top most TaskFragment in the task if there is any.
*/
+ @GuardedBy("mLock")
@VisibleForTesting
void placeActivityInTopContainer(@NonNull WindowContainerTransaction wct,
@NonNull Activity activity) {
@@ -876,6 +886,7 @@
/** Finds the activity below the given activity. */
@VisibleForTesting
@Nullable
+ @GuardedBy("mLock")
Activity findActivityBelow(@NonNull Activity activity) {
Activity activityBelow = null;
final TaskFragmentContainer container = getContainerWithActivity(activity);
@@ -1210,6 +1221,7 @@
return null;
}
+ @GuardedBy("mLock")
TaskFragmentContainer newContainer(@NonNull Activity pendingAppearedActivity, int taskId) {
return newContainer(pendingAppearedActivity, pendingAppearedActivity, taskId);
}
@@ -1320,9 +1332,6 @@
void removeContainer(@NonNull TaskFragmentContainer container) {
// Remove all split containers that included this one
final TaskContainer taskContainer = container.getTaskContainer();
- if (taskContainer == null) {
- return;
- }
taskContainer.mContainers.remove(container);
// Marked as a pending removal which will be removed after it is actually removed on the
// server side (#onTaskFragmentVanished).
@@ -1350,7 +1359,12 @@
* Removes a secondary container for the given primary container if an existing split is
* already registered.
*/
- void removeExistingSecondaryContainers(@NonNull WindowContainerTransaction wct,
+ // Suppress GuardedBy warning because lint asks to mark this method as
+ // @GuardedBy(existingSplitContainer.getSecondaryContainer().mController.mLock), which is mLock
+ // itself
+ @SuppressWarnings("GuardedBy")
+ @GuardedBy("mLock")
+ private void removeExistingSecondaryContainers(@NonNull WindowContainerTransaction wct,
@NonNull TaskFragmentContainer primaryContainer) {
// If the primary container was already in a split - remove the secondary container that
// is now covered by the new one that replaced it.
@@ -1368,6 +1382,7 @@
/**
* Returns the topmost not finished container in Task of given task id.
*/
+ @GuardedBy("mLock")
@Nullable
TaskFragmentContainer getTopActiveContainer(int taskId) {
final TaskContainer taskContainer = mTaskContainers.get(taskId);
@@ -1515,14 +1530,8 @@
}
final TaskFragmentContainer container = getContainerWithActivity(activity);
- // Don't launch placeholder if the container is occluded.
- if (container != null && container != getTopActiveContainer(container.getTaskId())) {
- return false;
- }
-
- final SplitContainer splitContainer = getActiveSplitForContainer(container);
- if (splitContainer != null && container.equals(splitContainer.getPrimaryContainer())) {
- // Don't launch placeholder in primary split container
+ if (container != null && !allowLaunchPlaceholder(container)) {
+ // We don't allow activity in this TaskFragment to launch placeholder.
return false;
}
@@ -1550,6 +1559,32 @@
return true;
}
+ /** Whether or not to allow activity in this container to launch placeholder. */
+ @GuardedBy("mLock")
+ private boolean allowLaunchPlaceholder(@NonNull TaskFragmentContainer container) {
+ final TaskFragmentContainer topContainer = getTopActiveContainer(container.getTaskId());
+ if (container != topContainer) {
+ // The container is not the top most.
+ if (!container.isVisible()) {
+ // In case the container is visible (the one on top may be transparent), we may
+ // still want to launch placeholder even if it is not the top most.
+ return false;
+ }
+ if (topContainer.isWaitingActivityAppear()) {
+ // When the top container appeared info is not sent by the server yet, the visible
+ // check above may not be reliable.
+ return false;
+ }
+ }
+
+ final SplitContainer splitContainer = getActiveSplitForContainer(container);
+ if (splitContainer != null && container.equals(splitContainer.getPrimaryContainer())) {
+ // Don't launch placeholder for primary split container.
+ return false;
+ }
+ return true;
+ }
+
/**
* Gets the activity options for starting the placeholder activity. In case the placeholder is
* launched when the Task is in the background, we don't want to bring the Task to the front.
@@ -1717,6 +1752,7 @@
}
@Nullable
+ @GuardedBy("mLock")
TaskFragmentContainer getContainer(@NonNull IBinder fragmentToken) {
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i).mContainers;
@@ -1730,6 +1766,7 @@
}
@Nullable
+ @GuardedBy("mLock")
TaskContainer getTaskContainer(int taskId) {
return mTaskContainers.get(taskId);
}
@@ -1738,6 +1775,7 @@
return mHandler;
}
+ @GuardedBy("mLock")
int getTaskId(@NonNull Activity activity) {
// Prefer to get the taskId from TaskFragmentContainer because Activity.getTaskId() is an
// IPC call.
@@ -1830,6 +1868,7 @@
/**
* @see #shouldRetainAssociatedContainer(TaskFragmentContainer, TaskFragmentContainer)
*/
+ @GuardedBy("mLock")
boolean shouldRetainAssociatedActivity(@NonNull TaskFragmentContainer finishingContainer,
@NonNull Activity associatedActivity) {
final TaskFragmentContainer associatedContainer = getContainerWithActivity(
@@ -1950,6 +1989,7 @@
@VisibleForTesting
class ActivityStartMonitor extends Instrumentation.ActivityMonitor {
@VisibleForTesting
+ @GuardedBy("mLock")
Intent mCurrentIntent;
@Override
@@ -2014,18 +2054,21 @@
@Override
public void onStartActivityResult(int result, @NonNull Bundle bOptions) {
super.onStartActivityResult(result, bOptions);
- if (mCurrentIntent != null && result != START_SUCCESS) {
- // Clear the pending appeared intent if the activity was not started successfully.
- final IBinder token = bOptions.getBinder(
- ActivityOptions.KEY_LAUNCH_TASK_FRAGMENT_TOKEN);
- if (token != null) {
- final TaskFragmentContainer container = getContainer(token);
- if (container != null) {
- container.clearPendingAppearedIntentIfNeeded(mCurrentIntent);
+ synchronized (mLock) {
+ if (mCurrentIntent != null && result != START_SUCCESS) {
+ // Clear the pending appeared intent if the activity was not started
+ // successfully.
+ final IBinder token = bOptions.getBinder(
+ ActivityOptions.KEY_LAUNCH_TASK_FRAGMENT_TOKEN);
+ if (token != null) {
+ final TaskFragmentContainer container = getContainer(token);
+ if (container != null) {
+ container.clearPendingAppearedIntentIfNeeded(mCurrentIntent);
+ }
}
}
+ mCurrentIntent = null;
}
- mCurrentIntent = null;
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 47253d3..9db9f87 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -39,7 +39,6 @@
import android.window.TaskFragmentCreationParams;
import android.window.WindowContainerTransaction;
-import androidx.annotation.GuardedBy;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -63,7 +62,10 @@
/**
* Controls the visual presentation of the splits according to the containers formed by
* {@link SplitController}.
+ *
+ * Note that all calls into this class must hold the {@link SplitController} internal lock.
*/
+@SuppressWarnings("GuardedBy")
class SplitPresenter extends JetpackTaskFragmentOrganizer {
@VisibleForTesting
static final int POSITION_START = 0;
@@ -154,12 +156,8 @@
void cleanupContainer(@NonNull WindowContainerTransaction wct,
@NonNull TaskFragmentContainer container, boolean shouldFinishDependent) {
container.finish(shouldFinishDependent, this, wct, mController);
-
- final TaskFragmentContainer newTopContainer = mController.getTopActiveContainer(
- container.getTaskId());
- if (newTopContainer != null) {
- mController.updateContainer(wct, newTopContainer);
- }
+ // Make sure the containers in the Task is up-to-date.
+ mController.updateContainersInTaskIfVisible(wct, container.getTaskId());
}
/**
@@ -167,7 +165,6 @@
* @return The newly created secondary container.
*/
@NonNull
- @GuardedBy("mController.mLock")
TaskFragmentContainer createNewSplitWithEmptySideContainer(
@NonNull WindowContainerTransaction wct, @NonNull Activity primaryActivity,
@NonNull Intent secondaryIntent, @NonNull SplitPairRule rule) {
@@ -214,7 +211,6 @@
* created and the activity will be re-parented to it.
* @param rule The split rule to be applied to the container.
*/
- @GuardedBy("mController.mLock")
void createNewSplitContainer(@NonNull WindowContainerTransaction wct,
@NonNull Activity primaryActivity, @NonNull Activity secondaryActivity,
@NonNull SplitPairRule rule) {
@@ -289,7 +285,6 @@
* @param rule The split rule to be applied to the container.
* @param isPlaceholder Whether the launch is a placeholder.
*/
- @GuardedBy("mController.mLock")
void startActivityToSide(@NonNull WindowContainerTransaction wct,
@NonNull Activity launchingActivity, @NonNull Intent activityIntent,
@Nullable Bundle activityOptions, @NonNull SplitRule rule,
@@ -332,7 +327,6 @@
* @param updatedContainer The task fragment that was updated and caused this split update.
* @param wct WindowContainerTransaction that this update should be performed with.
*/
- @GuardedBy("mController.mLock")
void updateSplitContainer(@NonNull SplitContainer splitContainer,
@NonNull TaskFragmentContainer updatedContainer,
@NonNull WindowContainerTransaction wct) {
@@ -373,7 +367,6 @@
updateTaskFragmentWindowingModeIfRegistered(wct, secondaryContainer, windowingMode);
}
- @GuardedBy("mController.mLock")
private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
@NonNull TaskFragmentContainer primaryContainer,
@NonNull TaskFragmentContainer secondaryContainer, @NonNull SplitRule splitRule,
@@ -397,7 +390,7 @@
* creation has not been reported from the server yet.
*/
// TODO(b/190433398): Handle resize if the fragment hasn't appeared yet.
- void resizeTaskFragmentIfRegistered(@NonNull WindowContainerTransaction wct,
+ private void resizeTaskFragmentIfRegistered(@NonNull WindowContainerTransaction wct,
@NonNull TaskFragmentContainer container,
@Nullable Rect bounds) {
if (container.getInfo() == null) {
@@ -524,7 +517,6 @@
return !(splitAttributes.getSplitType() instanceof ExpandContainersSplitType);
}
- @GuardedBy("mController.mLock")
@NonNull
SplitAttributes computeSplitAttributes(@NonNull TaskProperties taskProperties,
@NonNull SplitRule rule, @Nullable Pair<Size, Size> minDimensionsPair) {
@@ -576,8 +568,8 @@
}
@NonNull
- static Pair<Size, Size> getActivitiesMinDimensionsPair(@NonNull Activity primaryActivity,
- @NonNull Activity secondaryActivity) {
+ private static Pair<Size, Size> getActivitiesMinDimensionsPair(
+ @NonNull Activity primaryActivity, @NonNull Activity secondaryActivity) {
return new Pair<>(getMinDimensions(primaryActivity), getMinDimensions(secondaryActivity));
}
@@ -623,7 +615,7 @@
return new Size(windowLayout.minWidth, windowLayout.minHeight);
}
- static boolean boundsSmallerThanMinDimensions(@NonNull Rect bounds,
+ private static boolean boundsSmallerThanMinDimensions(@NonNull Rect bounds,
@Nullable Size minDimensions) {
if (minDimensions == null) {
return false;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index fcf0ac7..6bfdfe7 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -184,6 +184,11 @@
return allActivities;
}
+ /** Whether this TaskFragment is visible. */
+ boolean isVisible() {
+ return mInfo != null && mInfo.isVisible();
+ }
+
/** Whether the TaskFragment is in an intermediate state waiting for the server update.*/
boolean isInIntermediateState() {
if (mInfo == null) {
@@ -248,6 +253,7 @@
mPendingAppearedActivities.remove(activityToken);
}
+ @GuardedBy("mController.mLock")
void clearPendingAppearedActivities() {
final List<IBinder> cleanupActivities = new ArrayList<>(mPendingAppearedActivities);
// Clear mPendingAppearedActivities so that #getContainerWithActivity won't return the
@@ -447,6 +453,7 @@
* Removes all activities that belong to this process and finishes other containers/activities
* configured to finish together.
*/
+ @GuardedBy("mController.mLock")
void finish(boolean shouldFinishDependent, @NonNull SplitPresenter presenter,
@NonNull WindowContainerTransaction wct, @NonNull SplitController controller) {
if (!mIsFinished) {
@@ -471,6 +478,7 @@
mInfo = null;
}
+ @GuardedBy("mController.mLock")
private void finishActivities(boolean shouldFinishDependent, @NonNull SplitPresenter presenter,
@NonNull WindowContainerTransaction wct, @NonNull SplitController controller) {
// Finish own activities
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index b70b320..84b2bfc 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -35,8 +35,8 @@
import android.os.Bundle;
import android.os.IBinder;
import android.util.ArrayMap;
-import android.window.WindowProvider;
+import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiContext;
@@ -64,13 +64,19 @@
public class WindowLayoutComponentImpl implements WindowLayoutComponent {
private static final String TAG = "SampleExtension";
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
private final Map<Context, Consumer<WindowLayoutInfo>> mWindowLayoutChangeListeners =
new ArrayMap<>();
+ @GuardedBy("mLock")
private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
+ @GuardedBy("mLock")
private final List<CommonFoldingFeature> mLastReportedFoldingFeatures = new ArrayList<>();
+ @GuardedBy("mLock")
private final Map<IBinder, ConfigurationChangeListener> mConfigurationChangeListeners =
new ArrayMap<>();
@@ -85,7 +91,9 @@
/** Registers to listen to {@link CommonFoldingFeature} changes */
public void addFoldingStateChangedCallback(Consumer<List<CommonFoldingFeature>> consumer) {
- mFoldingFeatureProducer.addDataChangedCallback(consumer);
+ synchronized (mLock) {
+ mFoldingFeatureProducer.addDataChangedCallback(consumer);
+ }
}
/**
@@ -114,28 +122,32 @@
@Override
public void addWindowLayoutInfoListener(@NonNull @UiContext Context context,
@NonNull Consumer<WindowLayoutInfo> consumer) {
- if (mWindowLayoutChangeListeners.containsKey(context)
- // In theory this method can be called on the same consumer with different context.
- || mWindowLayoutChangeListeners.containsValue(consumer)) {
- return;
- }
- if (!context.isUiContext()) {
- throw new IllegalArgumentException("Context must be a UI Context, which should be"
- + " an Activity, WindowContext or InputMethodService");
- }
- mFoldingFeatureProducer.getData((features) -> {
- WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(context, features);
- consumer.accept(newWindowLayout);
- });
- mWindowLayoutChangeListeners.put(context, consumer);
+ synchronized (mLock) {
+ if (mWindowLayoutChangeListeners.containsKey(context)
+ // In theory this method can be called on the same consumer with different
+ // context.
+ || mWindowLayoutChangeListeners.containsValue(consumer)) {
+ return;
+ }
+ if (!context.isUiContext()) {
+ throw new IllegalArgumentException("Context must be a UI Context, which should be"
+ + " an Activity, WindowContext or InputMethodService");
+ }
+ mFoldingFeatureProducer.getData((features) -> {
+ WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(context, features);
+ consumer.accept(newWindowLayout);
+ });
+ mWindowLayoutChangeListeners.put(context, consumer);
- // TODO(b/258065175) Further extend this to ContextWrappers.
- if (context instanceof WindowProvider) {
final IBinder windowContextToken = context.getWindowContextToken();
- final ConfigurationChangeListener listener =
- new ConfigurationChangeListener(windowContextToken);
- context.registerComponentCallbacks(listener);
- mConfigurationChangeListeners.put(windowContextToken, listener);
+ if (windowContextToken != null) {
+ // We register component callbacks for window contexts. For activity contexts, they
+ // will receive callbacks from NotifyOnConfigurationChanged instead.
+ final ConfigurationChangeListener listener =
+ new ConfigurationChangeListener(windowContextToken);
+ context.registerComponentCallbacks(listener);
+ mConfigurationChangeListeners.put(windowContextToken, listener);
+ }
}
}
@@ -146,25 +158,29 @@
*/
@Override
public void removeWindowLayoutInfoListener(@NonNull Consumer<WindowLayoutInfo> consumer) {
- for (Context context : mWindowLayoutChangeListeners.keySet()) {
- if (!mWindowLayoutChangeListeners.get(context).equals(consumer)) {
- continue;
- }
- if (context instanceof WindowProvider) {
+ synchronized (mLock) {
+ for (Context context : mWindowLayoutChangeListeners.keySet()) {
+ if (!mWindowLayoutChangeListeners.get(context).equals(consumer)) {
+ continue;
+ }
final IBinder token = context.getWindowContextToken();
- context.unregisterComponentCallbacks(mConfigurationChangeListeners.get(token));
- mConfigurationChangeListeners.remove(token);
+ if (token != null) {
+ context.unregisterComponentCallbacks(mConfigurationChangeListeners.get(token));
+ mConfigurationChangeListeners.remove(token);
+ }
+ break;
}
- break;
+ mWindowLayoutChangeListeners.values().remove(consumer);
}
- mWindowLayoutChangeListeners.values().remove(consumer);
}
+ @GuardedBy("mLock")
@NonNull
- Set<Context> getContextsListeningForLayoutChanges() {
+ private Set<Context> getContextsListeningForLayoutChanges() {
return mWindowLayoutChangeListeners.keySet();
}
+ @GuardedBy("mLock")
private boolean isListeningForLayoutChanges(IBinder token) {
for (Context context: getContextsListeningForLayoutChanges()) {
if (token.equals(Context.getToken(context))) {
@@ -174,10 +190,6 @@
return false;
}
- protected boolean hasListeners() {
- return !mWindowLayoutChangeListeners.isEmpty();
- }
-
/**
* A convenience method to translate from the common feature state to the extensions feature
* state. More specifically, translates from {@link CommonFoldingFeature.State} to
@@ -201,13 +213,17 @@
}
private void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) {
- mLastReportedFoldingFeatures.clear();
- mLastReportedFoldingFeatures.addAll(storedFeatures);
- for (Context context : getContextsListeningForLayoutChanges()) {
- // Get the WindowLayoutInfo from the activity and pass the value to the layoutConsumer.
- Consumer<WindowLayoutInfo> layoutConsumer = mWindowLayoutChangeListeners.get(context);
- WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(context, storedFeatures);
- layoutConsumer.accept(newWindowLayout);
+ synchronized (mLock) {
+ mLastReportedFoldingFeatures.clear();
+ mLastReportedFoldingFeatures.addAll(storedFeatures);
+ for (Context context : getContextsListeningForLayoutChanges()) {
+ // Get the WindowLayoutInfo from the activity and pass the value to the
+ // layoutConsumer.
+ Consumer<WindowLayoutInfo> layoutConsumer = mWindowLayoutChangeListeners.get(
+ context);
+ WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(context, storedFeatures);
+ layoutConsumer.accept(newWindowLayout);
+ }
}
}
@@ -232,7 +248,10 @@
@NonNull
public WindowLayoutInfo getCurrentWindowLayoutInfo(int displayId,
@NonNull WindowConfiguration windowConfiguration) {
- return getWindowLayoutInfo(displayId, windowConfiguration, mLastReportedFoldingFeatures);
+ synchronized (mLock) {
+ return getWindowLayoutInfo(displayId, windowConfiguration,
+ mLastReportedFoldingFeatures);
+ }
}
/** @see #getWindowLayoutInfo(Context, List) */
@@ -308,9 +327,10 @@
return false;
}
final int windowingMode;
- if (context instanceof Activity) {
+ IBinder activityToken = context.getActivityToken();
+ if (activityToken != null) {
final Configuration taskConfig = ActivityClient.getInstance().getTaskConfiguration(
- context.getActivityToken());
+ activityToken);
if (taskConfig == null) {
// If we cannot determine the task configuration for any reason, it is likely that
// we won't be able to determine its position correctly as well. DisplayFeatures'
@@ -329,6 +349,7 @@
return !WindowConfiguration.inMultiWindowMode(windowingMode);
}
+ @GuardedBy("mLock")
private void onDisplayFeaturesChangedIfListening(@NonNull IBinder token) {
if (isListeningForLayoutChanges(token)) {
mFoldingFeatureProducer.getData(
@@ -340,13 +361,17 @@
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
super.onActivityCreated(activity, savedInstanceState);
- onDisplayFeaturesChangedIfListening(activity.getActivityToken());
+ synchronized (mLock) {
+ onDisplayFeaturesChangedIfListening(activity.getActivityToken());
+ }
}
@Override
public void onActivityConfigurationChanged(Activity activity) {
super.onActivityConfigurationChanged(activity);
- onDisplayFeaturesChangedIfListening(activity.getActivityToken());
+ synchronized (mLock) {
+ onDisplayFeaturesChangedIfListening(activity.getActivityToken());
+ }
}
}
@@ -359,7 +384,9 @@
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
- onDisplayFeaturesChangedIfListening(mToken);
+ synchronized (mLock) {
+ onDisplayFeaturesChangedIfListening(mToken);
+ }
}
@Override
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java
index 7624b69..fe60037 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java
@@ -27,9 +27,10 @@
*/
public class AcceptOnceConsumer<T> implements Consumer<T> {
private final Consumer<T> mCallback;
- private final DataProducer<T> mProducer;
+ private final AcceptOnceProducerCallback<T> mProducer;
- public AcceptOnceConsumer(@NonNull DataProducer<T> producer, @NonNull Consumer<T> callback) {
+ public AcceptOnceConsumer(@NonNull AcceptOnceProducerCallback<T> producer,
+ @NonNull Consumer<T> callback) {
mProducer = producer;
mCallback = callback;
}
@@ -37,6 +38,20 @@
@Override
public void accept(@NonNull T t) {
mCallback.accept(t);
- mProducer.removeDataChangedCallback(this);
+ mProducer.onConsumerReadyToBeRemoved(this);
+ }
+
+ /**
+ * Interface to allow the {@link AcceptOnceConsumer} to notify the client that created it,
+ * when it is ready to be removed. This allows the client to remove the consumer object
+ * when it deems it is safe to do so.
+ * @param <T> The type of data this callback accepts through {@link #onConsumerReadyToBeRemoved}
+ */
+ public interface AcceptOnceProducerCallback<T> {
+
+ /**
+ * Notifies that the given {@code callback} is ready to be removed
+ */
+ void onConsumerReadyToBeRemoved(Consumer<T> callback);
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
index cbaa277..46c925a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
@@ -19,6 +19,7 @@
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set;
@@ -31,11 +32,14 @@
*
* @param <T> The type of data this producer returns through {@link DataProducer#getData}.
*/
-public abstract class BaseDataProducer<T> implements DataProducer<T> {
+public abstract class BaseDataProducer<T> implements DataProducer<T>,
+ AcceptOnceConsumer.AcceptOnceProducerCallback<T> {
private final Object mLock = new Object();
@GuardedBy("mLock")
private final Set<Consumer<T>> mCallbacks = new LinkedHashSet<>();
+ @GuardedBy("mLock")
+ private final Set<Consumer<T>> mCallbacksToRemove = new HashSet<>();
/**
* Adds a callback to the set of callbacks listening for data. Data is delivered through
@@ -85,6 +89,26 @@
for (Consumer<T> callback : mCallbacks) {
callback.accept(value);
}
+ removeFinishedCallbacksLocked();
+ }
+ }
+
+ /**
+ * Removes any callbacks that notified us through {@link #onConsumerReadyToBeRemoved(Consumer)}
+ * that they are ready to be removed.
+ */
+ @GuardedBy("mLock")
+ private void removeFinishedCallbacksLocked() {
+ for (Consumer<T> callback: mCallbacksToRemove) {
+ mCallbacks.remove(callback);
+ }
+ mCallbacksToRemove.clear();
+ }
+
+ @Override
+ public void onConsumerReadyToBeRemoved(Consumer<T> callback) {
+ synchronized (mLock) {
+ mCallbacksToRemove.add(callback);
}
}
}
\ No newline at end of file
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
index bc03e4e..2f92a57 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
@@ -163,11 +163,17 @@
/** Creates a mock TaskFragmentInfo for the given TaskFragment. */
static TaskFragmentInfo createMockTaskFragmentInfo(@NonNull TaskFragmentContainer container,
@NonNull Activity activity) {
+ return createMockTaskFragmentInfo(container, activity, true /* isVisible */);
+ }
+
+ /** Creates a mock TaskFragmentInfo for the given TaskFragment. */
+ static TaskFragmentInfo createMockTaskFragmentInfo(@NonNull TaskFragmentContainer container,
+ @NonNull Activity activity, boolean isVisible) {
return new TaskFragmentInfo(container.getTaskFragmentToken(),
mock(WindowContainerToken.class),
new Configuration(),
1,
- true /* isVisible */,
+ isVisible,
Collections.singletonList(activity.getActivityToken()),
new Point(),
false /* isTaskClearedForReuse */,
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index 6725dfd..3cc31f9 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -1254,6 +1254,68 @@
verify(mEmbeddingCallback).accept(any());
}
+ @Test
+ public void testLaunchPlaceholderIfNecessary_nonEmbeddedActivity() {
+ // Launch placeholder for non embedded activity.
+ setupPlaceholderRule(mActivity);
+ mTransactionManager.startNewTransaction();
+ mSplitController.launchPlaceholderIfNecessary(mTransaction, mActivity,
+ true /* isOnCreated */);
+
+ verify(mTransaction).startActivityInTaskFragment(any(), any(), eq(PLACEHOLDER_INTENT),
+ any());
+ }
+
+ @Test
+ public void testLaunchPlaceholderIfNecessary_embeddedInTopTaskFragment() {
+ // Launch placeholder for activity in top TaskFragment.
+ setupPlaceholderRule(mActivity);
+ mTransactionManager.startNewTransaction();
+ final TaskFragmentContainer container = mSplitController.newContainer(mActivity, TASK_ID);
+ mSplitController.launchPlaceholderIfNecessary(mTransaction, mActivity,
+ true /* isOnCreated */);
+
+ assertTrue(container.hasActivity(mActivity.getActivityToken()));
+ verify(mTransaction).startActivityInTaskFragment(any(), any(), eq(PLACEHOLDER_INTENT),
+ any());
+ }
+
+ @Test
+ public void testLaunchPlaceholderIfNecessary_embeddedBelowTaskFragment() {
+ // Do not launch placeholder for invisible activity below the top TaskFragment.
+ setupPlaceholderRule(mActivity);
+ mTransactionManager.startNewTransaction();
+ final TaskFragmentContainer bottomTf = mSplitController.newContainer(mActivity, TASK_ID);
+ final TaskFragmentContainer topTf = mSplitController.newContainer(new Intent(), mActivity,
+ TASK_ID);
+ bottomTf.setInfo(mTransaction, createMockTaskFragmentInfo(bottomTf, mActivity,
+ false /* isVisible */));
+ topTf.setInfo(mTransaction, createMockTaskFragmentInfo(topTf, createMockActivity()));
+ assertFalse(bottomTf.isVisible());
+ mSplitController.launchPlaceholderIfNecessary(mTransaction, mActivity,
+ true /* isOnCreated */);
+
+ verify(mTransaction, never()).startActivityInTaskFragment(any(), any(), any(), any());
+ }
+
+ @Test
+ public void testLaunchPlaceholderIfNecessary_embeddedBelowTransparentTaskFragment() {
+ // Launch placeholder for visible activity below the top TaskFragment.
+ setupPlaceholderRule(mActivity);
+ mTransactionManager.startNewTransaction();
+ final TaskFragmentContainer bottomTf = mSplitController.newContainer(mActivity, TASK_ID);
+ final TaskFragmentContainer topTf = mSplitController.newContainer(new Intent(), mActivity,
+ TASK_ID);
+ bottomTf.setInfo(mTransaction, createMockTaskFragmentInfo(bottomTf, mActivity,
+ true /* isVisible */));
+ topTf.setInfo(mTransaction, createMockTaskFragmentInfo(topTf, createMockActivity()));
+ assertTrue(bottomTf.isVisible());
+ mSplitController.launchPlaceholderIfNecessary(mTransaction, mActivity,
+ true /* isOnCreated */);
+
+ verify(mTransaction).startActivityInTaskFragment(any(), any(), any(), any());
+ }
+
/** Creates a mock activity in the organizer process. */
private Activity createMockActivity() {
return createMockActivity(TASK_ID);
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
index 5c3ba72..9877236 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
@@ -500,6 +500,29 @@
assertEquals(2, taskContainer.indexOf(tf1));
}
+ @Test
+ public void testIsVisible() {
+ final TaskContainer taskContainer = createTestTaskContainer();
+ final TaskFragmentContainer container = new TaskFragmentContainer(
+ null /* pendingAppearedActivity */, new Intent(), taskContainer, mController,
+ null /* pairedPrimaryTaskFragment */);
+
+ // Not visible when there is not appeared.
+ assertFalse(container.isVisible());
+
+ // Respect info.isVisible.
+ TaskFragmentInfo info = createMockTaskFragmentInfo(container, mActivity,
+ true /* isVisible */);
+ container.setInfo(mTransaction, info);
+
+ assertTrue(container.isVisible());
+
+ info = createMockTaskFragmentInfo(container, mActivity, false /* isVisible */);
+ container.setInfo(mTransaction, info);
+
+ assertFalse(container.isVisible());
+ }
+
/** Creates a mock activity in the organizer process. */
private Activity createMockActivity() {
final Activity activity = mock(Activity.class);
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 540ae7c..78d74d74 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -17,79 +17,79 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="pip_phone_close" msgid="5783752637260411309">"Zatvori"</string>
- <string name="pip_phone_expand" msgid="2579292903468287504">"Proširi"</string>
- <string name="pip_phone_settings" msgid="5468987116750491918">"Podešavanja"</string>
- <string name="pip_phone_enter_split" msgid="7042877263880641911">"Uđi na podeljeni ekran"</string>
- <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string>
- <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je slika u slici"</string>
- <string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da biste otvorili podešavanja i isključili je."</string>
- <string name="pip_play" msgid="3496151081459417097">"Pusti"</string>
- <string name="pip_pause" msgid="690688849510295232">"Pauziraj"</string>
- <string name="pip_skip_to_next" msgid="8403429188794867653">"Pređi na sledeće"</string>
- <string name="pip_skip_to_prev" msgid="7172158111196394092">"Pređi na prethodno"</string>
- <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Promenite veličinu"</string>
- <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Stavite u tajnu memoriju"</string>
- <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Uklonite iz tajne memorije"</string>
- <string name="dock_forced_resizable" msgid="1749750436092293116">"Aplikacija možda neće raditi sa podeljenim ekranom."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podržava podeljeni ekran."</string>
- <string name="dock_multi_instances_not_supported_text" msgid="5242868470666346929">"Ova aplikacija može da se otvori samo u jednom prozoru."</string>
- <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
- <string name="accessibility_divider" msgid="703810061635792791">"Razdelnik podeljenog ekrana"</string>
- <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Režim celog ekrana za levi ekran"</string>
- <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Levi ekran 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi ekran 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Levi ekran 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Režim celog ekrana za donji ekran"</string>
- <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Režim celog ekrana za gornji ekran"</string>
- <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gornji ekran 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji ekran 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gornji ekran 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Režim celog ekrana za donji ekran"</string>
- <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korišćenje režima jednom rukom"</string>
- <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Da biste izašli, prevucite nagore od dna ekrana ili dodirnite bilo gde iznad aplikacije"</string>
- <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pokrenite režim jednom rukom"</string>
- <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Izađite iz režima jednom rukom"</string>
- <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Podešavanja za <xliff:g id="APP_NAME">%1$s</xliff:g> oblačiće"</string>
- <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Preklapanje"</string>
- <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Dodaj ponovo u grupu"</string>
- <string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
- <string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g> i još <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
- <string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"Premesti gore levo"</string>
- <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Premesti gore desno"</string>
- <string name="bubble_accessibility_action_move_bottom_left" msgid="850271002773745634">"Premesti dole levo"</string>
- <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Premesti dole desno"</string>
- <string name="bubbles_app_settings" msgid="3617224938701566416">"Podešavanja za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
- <string name="bubble_dismiss_text" msgid="8816558050659478158">"Odbaci oblačić"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne koristi oblačiće za konverzaciju"</string>
- <string name="bubbles_user_education_title" msgid="2112319053732691899">"Ćaskajte u oblačićima"</string>
- <string name="bubbles_user_education_description" msgid="4215862563054175407">"Nove konverzacije se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da biste otvorili oblačić. Prevucite da biste ga premestili."</string>
- <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Kontrolišite oblačiće u bilo kom trenutku"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Dodirnite Upravljajte da biste isključili oblačiće iz ove aplikacije"</string>
- <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Važi"</string>
- <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nema nedavnih oblačića"</string>
- <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Ovde se prikazuju nedavni i odbačeni oblačići"</string>
- <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
- <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljajte"</string>
- <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string>
- <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste restartovali ovu aplikaciju radi boljeg prikaza."</string>
- <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Imate problema sa kamerom?\nDodirnite da biste ponovo uklopili"</string>
- <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije rešen?\nDodirnite da biste vratili"</string>
- <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema sa kamerom? Dodirnite da biste odbacili."</string>
- <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vidite i uradite više"</string>
- <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Prevucite drugu aplikaciju da biste koristili podeljeni ekran"</string>
- <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da biste promenili njenu poziciju"</string>
- <string name="letterbox_education_got_it" msgid="4057634570866051177">"Važi"</string>
- <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za još informacija."</string>
- <string name="maximize_button_text" msgid="1650859196290301963">"Uvećajte"</string>
- <string name="minimize_button_text" msgid="271592547935841753">"Umanjite"</string>
- <string name="close_button_text" msgid="2913281996024033299">"Zatvorite"</string>
- <string name="back_button_text" msgid="1469718707134137085">"Nazad"</string>
- <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
- <string name="fullscreen_text" msgid="1162316685217676079">"Preko celog ekrana"</string>
- <string name="desktop_text" msgid="1077633567027630454">"Režim za računare"</string>
- <string name="split_screen_text" msgid="1396336058129570886">"Podeljeni ekran"</string>
- <string name="more_button_text" msgid="3655388105592893530">"Još"</string>
- <string name="float_button_text" msgid="9221657008391364581">"Plutajuće"</string>
+ <string name="pip_phone_close" msgid="5783752637260411309">"Затвори"</string>
+ <string name="pip_phone_expand" msgid="2579292903468287504">"Прошири"</string>
+ <string name="pip_phone_settings" msgid="5468987116750491918">"Подешавања"</string>
+ <string name="pip_phone_enter_split" msgid="7042877263880641911">"Уђи на подељени екран"</string>
+ <string name="pip_menu_title" msgid="5393619322111827096">"Мени"</string>
+ <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> је слика у слици"</string>
+ <string name="pip_notification_message" msgid="8854051911700302620">"Ако не желите да <xliff:g id="NAME">%s</xliff:g> користи ову функцију, додирните да бисте отворили подешавања и искључили је."</string>
+ <string name="pip_play" msgid="3496151081459417097">"Пусти"</string>
+ <string name="pip_pause" msgid="690688849510295232">"Паузирај"</string>
+ <string name="pip_skip_to_next" msgid="8403429188794867653">"Пређи на следеће"</string>
+ <string name="pip_skip_to_prev" msgid="7172158111196394092">"Пређи на претходно"</string>
+ <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Промените величину"</string>
+ <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Ставите у тајну меморију"</string>
+ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Уклоните из тајне меморије"</string>
+ <string name="dock_forced_resizable" msgid="1749750436092293116">"Апликација можда неће радити са подељеним екраном."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Апликација не подржава подељени екран."</string>
+ <string name="dock_multi_instances_not_supported_text" msgid="5242868470666346929">"Ова апликација може да се отвори само у једном прозору."</string>
+ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликација можда неће функционисати на секундарном екрану."</string>
+ <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликација не подржава покретање на секундарним екранима."</string>
+ <string name="accessibility_divider" msgid="703810061635792791">"Разделник подељеног екрана"</string>
+ <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Режим целог екрана за леви екран"</string>
+ <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Леви екран 70%"</string>
+ <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Леви екран 50%"</string>
+ <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Леви екран 30%"</string>
+ <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Режим целог екрана за доњи екран"</string>
+ <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Режим целог екрана за горњи екран"</string>
+ <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Горњи екран 70%"</string>
+ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горњи екран 50%"</string>
+ <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горњи екран 30%"</string>
+ <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Режим целог екрана за доњи екран"</string>
+ <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Коришћење режима једном руком"</string>
+ <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Да бисте изашли, превуците нагоре од дна екрана или додирните било где изнад апликације"</string>
+ <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Покрените режим једном руком"</string>
+ <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Изађите из режима једном руком"</string>
+ <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Подешавања за <xliff:g id="APP_NAME">%1$s</xliff:g> облачиће"</string>
+ <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Преклапање"</string>
+ <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Додај поново у групу"</string>
+ <string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из апликације <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+ <string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из апликације <xliff:g id="APP_NAME">%2$s</xliff:g> и још <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
+ <string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"Премести горе лево"</string>
+ <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Премести горе десно"</string>
+ <string name="bubble_accessibility_action_move_bottom_left" msgid="850271002773745634">"Премести доле лево"</string>
+ <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Премести доле десно"</string>
+ <string name="bubbles_app_settings" msgid="3617224938701566416">"Подешавања за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
+ <string name="bubble_dismiss_text" msgid="8816558050659478158">"Одбаци облачић"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не користи облачиће за конверзацију"</string>
+ <string name="bubbles_user_education_title" msgid="2112319053732691899">"Ћаскајте у облачићима"</string>
+ <string name="bubbles_user_education_description" msgid="4215862563054175407">"Нове конверзације се приказују као плутајуће иконе или облачићи. Додирните да бисте отворили облачић. Превуците да бисте га преместили."</string>
+ <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Контролишите облачиће у било ком тренутку"</string>
+ <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Додирните Управљајте да бисте искључили облачиће из ове апликације"</string>
+ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Важи"</string>
+ <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Нема недавних облачића"</string>
+ <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Овде се приказују недавни и одбачени облачићи"</string>
+ <string name="notification_bubble_title" msgid="6082910224488253378">"Облачић"</string>
+ <string name="manage_bubbles_text" msgid="7730624269650594419">"Управљајте"</string>
+ <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Облачић је одбачен."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Додирните да бисте рестартовали ову апликацију ради бољег приказа."</string>
+ <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблема са камером?\nДодирните да бисте поново уклопили"</string>
+ <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблем није решен?\nДодирните да бисте вратили"</string>
+ <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немате проблема са камером? Додирните да бисте одбацили."</string>
+ <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Видите и урадите више"</string>
+ <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Превуците другу апликацију да бисте користили подељени екран"</string>
+ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Двапут додирните изван апликације да бисте променили њену позицију"</string>
+ <string name="letterbox_education_got_it" msgid="4057634570866051177">"Важи"</string>
+ <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Проширите за још информација."</string>
+ <string name="maximize_button_text" msgid="1650859196290301963">"Увећајте"</string>
+ <string name="minimize_button_text" msgid="271592547935841753">"Умањите"</string>
+ <string name="close_button_text" msgid="2913281996024033299">"Затворите"</string>
+ <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Идентификатор"</string>
+ <string name="fullscreen_text" msgid="1162316685217676079">"Преко целог екрана"</string>
+ <string name="desktop_text" msgid="1077633567027630454">"Режим за рачунаре"</string>
+ <string name="split_screen_text" msgid="1396336058129570886">"Подељени екран"</string>
+ <string name="more_button_text" msgid="3655388105592893530">"Још"</string>
+ <string name="float_button_text" msgid="9221657008391364581">"Плутајуће"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
index 51a1262..e850979 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
@@ -17,18 +17,18 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika u slici"</string>
- <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez naslova)"</string>
- <string name="pip_close" msgid="2955969519031223530">"Zatvori"</string>
- <string name="pip_fullscreen" msgid="7278047353591302554">"Ceo ekran"</string>
- <string name="pip_move" msgid="158770205886688553">"Premesti"</string>
- <string name="pip_expand" msgid="1051966011679297308">"Proširi"</string>
- <string name="pip_collapse" msgid="3903295106641385962">"Skupi"</string>
- <string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">" HOME "</annotation>" za kontrole"</string>
- <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meni Slika u slici."</string>
- <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pomerite nalevo"</string>
- <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pomerite nadesno"</string>
- <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pomerite nagore"</string>
- <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pomerite nadole"</string>
- <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotovo"</string>
+ <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Слика у слици"</string>
+ <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Програм без наслова)"</string>
+ <string name="pip_close" msgid="2955969519031223530">"Затвори"</string>
+ <string name="pip_fullscreen" msgid="7278047353591302554">"Цео екран"</string>
+ <string name="pip_move" msgid="158770205886688553">"Премести"</string>
+ <string name="pip_expand" msgid="1051966011679297308">"Прошири"</string>
+ <string name="pip_collapse" msgid="3903295106641385962">"Скупи"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Двапут притисните "<annotation icon="home_icon">" HOME "</annotation>" за контроле"</string>
+ <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Мени Слика у слици."</string>
+ <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Померите налево"</string>
+ <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Померите надесно"</string>
+ <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Померите нагоре"</string>
+ <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Померите надоле"</string>
+ <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 4a937cf..4b10f5a 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -33,8 +33,7 @@
<string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"अनस्ट्यास गर्नुहोस्"</string>
<string name="dock_forced_resizable" msgid="1749750436092293116">"एप विभाजित स्क्रिनमा काम नगर्न सक्छ।"</string>
<string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"अनुप्रयोगले विभाजित-स्क्रिनलाई समर्थन गर्दैन।"</string>
- <!-- no translation found for dock_multi_instances_not_supported_text (5242868470666346929) -->
- <skip />
+ <string name="dock_multi_instances_not_supported_text" msgid="5242868470666346929">"यो एप एउटा विन्डोमा मात्र खोल्न मिल्छ।"</string>
<string name="forced_resizable_secondary_display" msgid="1768046938673582671">"यो एपले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string>
<string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रिन छुट्याउने"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 2b7600c..f2afefe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -2923,8 +2923,10 @@
.withEndActions(() -> {
View child = mManageMenu.getChildAt(0);
child.requestAccessibilityFocus();
- // Update the AV's obscured touchable region for the new visibility state.
- mExpandedBubble.getExpandedView().updateObscuredTouchableRegion();
+ if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ // Update the AV's obscured touchable region for the new state.
+ mExpandedBubble.getExpandedView().updateObscuredTouchableRegion();
+ }
})
.start();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index c743582..09f5cf1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -61,6 +61,7 @@
import com.android.wm.shell.desktopmode.DesktopModeController;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
+import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
import com.android.wm.shell.displayareahelper.DisplayAreaHelperController;
import com.android.wm.shell.draganddrop.DragAndDropController;
@@ -677,7 +678,11 @@
@WMSingleton
@Provides
static Optional<DesktopMode> provideDesktopMode(
- Optional<DesktopModeController> desktopModeController) {
+ Optional<DesktopModeController> desktopModeController,
+ Optional<DesktopTasksController> desktopTasksController) {
+ if (DesktopModeStatus.isProto2Enabled()) {
+ return desktopTasksController.map(DesktopTasksController::asDesktopMode);
+ }
return desktopModeController.map(DesktopModeController::asDesktopMode);
}
@@ -700,6 +705,23 @@
@BindsOptionalOf
@DynamicOverride
+ abstract DesktopTasksController optionalDesktopTasksController();
+
+ @WMSingleton
+ @Provides
+ static Optional<DesktopTasksController> providesDesktopTasksController(
+ @DynamicOverride Optional<Lazy<DesktopTasksController>> desktopTasksController) {
+ // Use optional-of-lazy for the dependency that this provider relies on.
+ // Lazy ensures that this provider will not be the cause the dependency is created
+ // when it will not be returned due to the condition below.
+ if (DesktopModeStatus.isProto2Enabled()) {
+ return desktopTasksController.map(Lazy::get);
+ }
+ return Optional.empty();
+ }
+
+ @BindsOptionalOf
+ @DynamicOverride
abstract DesktopModeTaskRepository optionalDesktopModeTaskRepository();
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 6be8305..701a3a4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -50,6 +50,7 @@
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.desktopmode.DesktopModeController;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
+import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.freeform.FreeformComponents;
import com.android.wm.shell.freeform.FreeformTaskListener;
@@ -189,7 +190,8 @@
ShellTaskOrganizer taskOrganizer,
DisplayController displayController,
SyncTransactionQueue syncQueue,
- Optional<DesktopModeController> desktopModeController) {
+ Optional<DesktopModeController> desktopModeController,
+ Optional<DesktopTasksController> desktopTasksController) {
return new CaptionWindowDecorViewModel(
context,
mainHandler,
@@ -197,7 +199,8 @@
taskOrganizer,
displayController,
syncQueue,
- desktopModeController);
+ desktopModeController,
+ desktopTasksController);
}
//
@@ -616,6 +619,22 @@
@WMSingleton
@Provides
@DynamicOverride
+ static DesktopTasksController provideDesktopTasksController(
+ Context context,
+ ShellInit shellInit,
+ ShellController shellController,
+ ShellTaskOrganizer shellTaskOrganizer,
+ Transitions transitions,
+ @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
+ @ShellMainThread ShellExecutor mainExecutor
+ ) {
+ return new DesktopTasksController(context, shellInit, shellController, shellTaskOrganizer,
+ transitions, desktopModeTaskRepository, mainExecutor);
+ }
+
+ @WMSingleton
+ @Provides
+ @DynamicOverride
static DesktopModeTaskRepository provideDesktopModeTaskRepository() {
return new DesktopModeTaskRepository();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
index 67f4a19..055949f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
@@ -70,9 +70,13 @@
* @return {@code true} if active
*/
public static boolean isActive(Context context) {
- if (!IS_SUPPORTED) {
+ if (!isAnyEnabled()) {
return false;
}
+ if (isProto2Enabled()) {
+ // Desktop mode is always active in prototype 2
+ return true;
+ }
try {
int result = Settings.System.getIntForUser(context.getContentResolver(),
Settings.System.DESKTOP_MODE, UserHandle.USER_CURRENT);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
new file mode 100644
index 0000000..3341470
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode
+
+import android.app.ActivityManager
+import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
+import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
+import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
+import android.app.WindowConfiguration.WindowingMode
+import android.content.Context
+import android.os.IBinder
+import android.view.SurfaceControl
+import android.view.WindowManager.TRANSIT_CHANGE
+import android.view.WindowManager.TRANSIT_OPEN
+import android.view.WindowManager.TRANSIT_TO_FRONT
+import android.window.TransitionInfo
+import android.window.TransitionRequestInfo
+import android.window.WindowContainerTransaction
+import androidx.annotation.BinderThread
+import com.android.internal.protolog.common.ProtoLog
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.common.ExecutorUtils
+import com.android.wm.shell.common.ExternalInterfaceBinder
+import com.android.wm.shell.common.RemoteCallable
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.annotations.ExternalThread
+import com.android.wm.shell.common.annotations.ShellMainThread
+import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+import com.android.wm.shell.sysui.ShellController
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.sysui.ShellSharedConstants
+import com.android.wm.shell.transition.Transitions
+import java.util.concurrent.Executor
+import java.util.function.Consumer
+
+/** Handles moving tasks in and out of desktop */
+class DesktopTasksController(
+ private val context: Context,
+ shellInit: ShellInit,
+ private val shellController: ShellController,
+ private val shellTaskOrganizer: ShellTaskOrganizer,
+ private val transitions: Transitions,
+ private val desktopModeTaskRepository: DesktopModeTaskRepository,
+ @ShellMainThread private val mainExecutor: ShellExecutor
+) : RemoteCallable<DesktopTasksController>, Transitions.TransitionHandler {
+
+ private val desktopMode: DesktopModeImpl
+
+ init {
+ desktopMode = DesktopModeImpl()
+ if (DesktopModeStatus.isProto2Enabled()) {
+ shellInit.addInitCallback({ onInit() }, this)
+ }
+ }
+
+ private fun onInit() {
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
+ shellController.addExternalInterface(
+ ShellSharedConstants.KEY_EXTRA_SHELL_DESKTOP_MODE,
+ { createExternalInterface() },
+ this
+ )
+ transitions.addHandler(this)
+ }
+
+ /** Show all tasks, that are part of the desktop, on top of launcher */
+ fun showDesktopApps() {
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps")
+ val wct = WindowContainerTransaction()
+
+ bringDesktopAppsToFront(wct)
+
+ // Execute transaction if there are pending operations
+ if (!wct.isEmpty) {
+ if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+ transitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */)
+ } else {
+ shellTaskOrganizer.applyTransaction(wct)
+ }
+ }
+ }
+
+ /** Move a task with given `taskId` to desktop */
+ fun moveToDesktop(taskId: Int) {
+ shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> moveToDesktop(task) }
+ }
+
+ /** Move a task to desktop */
+ fun moveToDesktop(task: ActivityManager.RunningTaskInfo) {
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToDesktop: %d", task.taskId)
+
+ val wct = WindowContainerTransaction()
+ // Bring other apps to front first
+ bringDesktopAppsToFront(wct)
+
+ wct.setWindowingMode(task.getToken(), WINDOWING_MODE_FREEFORM)
+ wct.reorder(task.getToken(), true /* onTop */)
+
+ if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+ transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */)
+ } else {
+ shellTaskOrganizer.applyTransaction(wct)
+ }
+ }
+
+ /** Move a task with given `taskId` to fullscreen */
+ fun moveToFullscreen(taskId: Int) {
+ shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> moveToFullscreen(task) }
+ }
+
+ /** Move a task to fullscreen */
+ fun moveToFullscreen(task: ActivityManager.RunningTaskInfo) {
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToFullscreen: %d", task.taskId)
+
+ val wct = WindowContainerTransaction()
+ wct.setWindowingMode(task.getToken(), WINDOWING_MODE_FULLSCREEN)
+ wct.setBounds(task.getToken(), null)
+ if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+ transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */)
+ } else {
+ shellTaskOrganizer.applyTransaction(wct)
+ }
+ }
+
+ /**
+ * Get windowing move for a given `taskId`
+ *
+ * @return [WindowingMode] for the task or [WINDOWING_MODE_UNDEFINED] if task is not found
+ */
+ @WindowingMode
+ fun getTaskWindowingMode(taskId: Int): Int {
+ return shellTaskOrganizer.getRunningTaskInfo(taskId)?.windowingMode
+ ?: WINDOWING_MODE_UNDEFINED
+ }
+
+ private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) {
+ val activeTasks = desktopModeTaskRepository.getActiveTasks()
+
+ // Skip if all tasks are already visible
+ if (activeTasks.isNotEmpty() && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) {
+ ProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "bringDesktopAppsToFront: active tasks are already in front, skipping."
+ )
+ return
+ }
+
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront")
+
+ // First move home to front and then other tasks on top of it
+ moveHomeTaskToFront(wct)
+
+ val allTasksInZOrder = desktopModeTaskRepository.getFreeformTasksInZOrder()
+ activeTasks
+ // Sort descending as the top task is at index 0. It should be ordered to top last
+ .sortedByDescending { taskId -> allTasksInZOrder.indexOf(taskId) }
+ .mapNotNull { taskId -> shellTaskOrganizer.getRunningTaskInfo(taskId) }
+ .forEach { task -> wct.reorder(task.token, true /* onTop */) }
+ }
+
+ private fun moveHomeTaskToFront(wct: WindowContainerTransaction) {
+ shellTaskOrganizer
+ .getRunningTasks(context.displayId)
+ .firstOrNull { task -> task.activityType == ACTIVITY_TYPE_HOME }
+ ?.let { homeTask -> wct.reorder(homeTask.getToken(), true /* onTop */) }
+ }
+
+ override fun getContext(): Context {
+ return context
+ }
+
+ override fun getRemoteCallExecutor(): ShellExecutor {
+ return mainExecutor
+ }
+
+ override fun startAnimation(
+ transition: IBinder,
+ info: TransitionInfo,
+ startTransaction: SurfaceControl.Transaction,
+ finishTransaction: SurfaceControl.Transaction,
+ finishCallback: Transitions.TransitionFinishCallback
+ ): Boolean {
+ // This handler should never be the sole handler, so should not animate anything.
+ return false
+ }
+
+ override fun handleRequest(
+ transition: IBinder,
+ request: TransitionRequestInfo
+ ): WindowContainerTransaction? {
+ // Check if we should skip handling this transition
+ val task: ActivityManager.RunningTaskInfo? = request.triggerTask
+ val shouldHandleRequest =
+ when {
+ // Only handle open or to front transitions
+ request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> false
+ // Only handle when it is a task transition
+ task == null -> false
+ // Only handle standard type tasks
+ task.activityType != ACTIVITY_TYPE_STANDARD -> false
+ // Only handle fullscreen or freeform tasks
+ task.windowingMode != WINDOWING_MODE_FULLSCREEN &&
+ task.windowingMode != WINDOWING_MODE_FREEFORM -> false
+ // Otherwise process it
+ else -> true
+ }
+
+ if (!shouldHandleRequest) {
+ return null
+ }
+
+ val activeTasks = desktopModeTaskRepository.getActiveTasks()
+
+ // Check if we should switch a fullscreen task to freeform
+ if (task?.windowingMode == WINDOWING_MODE_FULLSCREEN) {
+ // If there are any visible desktop tasks, switch the task to freeform
+ if (activeTasks.any { desktopModeTaskRepository.isVisibleTask(it) }) {
+ ProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController#handleRequest: switch fullscreen task to freeform," +
+ " taskId=%d",
+ task.taskId
+ )
+ return WindowContainerTransaction().apply {
+ setWindowingMode(task.token, WINDOWING_MODE_FREEFORM)
+ }
+ }
+ }
+
+ // CHeck if we should switch a freeform task to fullscreen
+ if (task?.windowingMode == WINDOWING_MODE_FREEFORM) {
+ // If no visible desktop tasks, switch this task to freeform as the transition came
+ // outside of this controller
+ if (activeTasks.none { desktopModeTaskRepository.isVisibleTask(it) }) {
+ ProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController#handleRequest: switch freeform task to fullscreen," +
+ " taskId=%d",
+ task.taskId
+ )
+ return WindowContainerTransaction().apply {
+ setWindowingMode(task.token, WINDOWING_MODE_FULLSCREEN)
+ setBounds(task.token, null)
+ }
+ }
+ }
+ return null
+ }
+
+ /** Creates a new instance of the external interface to pass to another process. */
+ private fun createExternalInterface(): ExternalInterfaceBinder {
+ return IDesktopModeImpl(this)
+ }
+
+ /** Get connection interface between sysui and shell */
+ fun asDesktopMode(): DesktopMode {
+ return desktopMode
+ }
+
+ /**
+ * Adds a listener to find out about changes in the visibility of freeform tasks.
+ *
+ * @param listener the listener to add.
+ * @param callbackExecutor the executor to call the listener on.
+ */
+ fun addListener(listener: VisibleTasksListener, callbackExecutor: Executor) {
+ desktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor)
+ }
+
+ /** The interface for calls from outside the shell, within the host process. */
+ @ExternalThread
+ private inner class DesktopModeImpl : DesktopMode {
+ override fun addListener(listener: VisibleTasksListener, callbackExecutor: Executor) {
+ mainExecutor.execute {
+ this@DesktopTasksController.addListener(listener, callbackExecutor)
+ }
+ }
+ }
+
+ /** The interface for calls from outside the host process. */
+ @BinderThread
+ private class IDesktopModeImpl(private var controller: DesktopTasksController?) :
+ IDesktopMode.Stub(), ExternalInterfaceBinder {
+ /** Invalidates this instance, preventing future calls from updating the controller. */
+ override fun invalidate() {
+ controller = null
+ }
+
+ override fun showDesktopApps() {
+ ExecutorUtils.executeRemoteCallWithTaskPermission(
+ controller,
+ "showDesktopApps",
+ Consumer(DesktopTasksController::showDesktopApps)
+ )
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 5be29db..8ddc3c04 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -204,10 +204,6 @@
private boolean mIsDropEntering;
private boolean mIsExiting;
- /** The target stage to dismiss to when unlock after folded. */
- @StageType
- private int mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
-
private DefaultMixedHandler mMixedHandler;
private final Toast mSplitUnsupportedToast;
@@ -976,20 +972,6 @@
return;
}
- if (!mKeyguardShowing && mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) {
- if (ENABLE_SHELL_TRANSITIONS) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- prepareExitSplitScreen(mTopStageAfterFoldDismiss, wct);
- mSplitTransitions.startDismissTransition(wct, this,
- mTopStageAfterFoldDismiss, EXIT_REASON_DEVICE_FOLDED);
- } else {
- exitSplitScreen(
- mTopStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
- EXIT_REASON_DEVICE_FOLDED);
- }
- return;
- }
-
setDividerVisibility(!mKeyguardShowing, null);
}
@@ -1613,7 +1595,7 @@
mSplitLayout.flingDividerToDismiss(
mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT,
EXIT_REASON_APP_FINISHED);
- } else if (!isSplitScreenVisible()) {
+ } else if (!isSplitScreenVisible() && !mIsSplitEntering) {
exitSplitScreen(null /* childrenToTop */, EXIT_REASON_APP_FINISHED);
}
} else if (isSideStage && hasChildren && !mMainStage.isActive()) {
@@ -1828,14 +1810,28 @@
sendOnBoundsChanged();
}
- private void onFoldedStateChanged(boolean folded) {
- mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
+ @VisibleForTesting
+ void onFoldedStateChanged(boolean folded) {
+ int topStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
if (!folded) return;
+ if (!mMainStage.isActive()) return;
+
if (mMainStage.isFocused()) {
- mTopStageAfterFoldDismiss = STAGE_TYPE_MAIN;
+ topStageAfterFoldDismiss = STAGE_TYPE_MAIN;
} else if (mSideStage.isFocused()) {
- mTopStageAfterFoldDismiss = STAGE_TYPE_SIDE;
+ topStageAfterFoldDismiss = STAGE_TYPE_SIDE;
+ }
+
+ if (ENABLE_SHELL_TRANSITIONS) {
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ prepareExitSplitScreen(topStageAfterFoldDismiss, wct);
+ mSplitTransitions.startDismissTransition(wct, this,
+ topStageAfterFoldDismiss, EXIT_REASON_DEVICE_FOLDED);
+ } else {
+ exitSplitScreen(
+ topStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
+ EXIT_REASON_DEVICE_FOLDED);
}
}
@@ -2118,7 +2114,6 @@
// Update divider state after animation so that it is still around and positioned
// properly for the animation itself.
mSplitLayout.release();
- mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 42e2b3f..299284f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -53,6 +53,7 @@
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.DesktopModeController;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
+import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.transition.Transitions;
@@ -75,6 +76,7 @@
private final SyncTransactionQueue mSyncQueue;
private FreeformTaskTransitionStarter mTransitionStarter;
private Optional<DesktopModeController> mDesktopModeController;
+ private Optional<DesktopTasksController> mDesktopTasksController;
private boolean mTransitionDragActive;
private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -90,7 +92,8 @@
ShellTaskOrganizer taskOrganizer,
DisplayController displayController,
SyncTransactionQueue syncQueue,
- Optional<DesktopModeController> desktopModeController) {
+ Optional<DesktopModeController> desktopModeController,
+ Optional<DesktopTasksController> desktopTasksController) {
this(
context,
mainHandler,
@@ -99,6 +102,7 @@
displayController,
syncQueue,
desktopModeController,
+ desktopTasksController,
new CaptionWindowDecoration.Factory(),
new InputMonitorFactory());
}
@@ -112,6 +116,7 @@
DisplayController displayController,
SyncTransactionQueue syncQueue,
Optional<DesktopModeController> desktopModeController,
+ Optional<DesktopTasksController> desktopTasksController,
CaptionWindowDecoration.Factory captionWindowDecorFactory,
InputMonitorFactory inputMonitorFactory) {
mContext = context;
@@ -122,6 +127,7 @@
mDisplayController = displayController;
mSyncQueue = syncQueue;
mDesktopModeController = desktopModeController;
+ mDesktopTasksController = desktopTasksController;
mCaptionWindowDecorFactory = captionWindowDecorFactory;
mInputMonitorFactory = inputMonitorFactory;
@@ -242,11 +248,13 @@
decoration.createHandleMenu();
} else if (id == R.id.desktop_button) {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
+ mDesktopTasksController.ifPresent(c -> c.moveToDesktop(mTaskId));
decoration.closeHandleMenu();
} else if (id == R.id.fullscreen_button) {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false));
+ mDesktopTasksController.ifPresent(c -> c.moveToFullscreen(mTaskId));
decoration.closeHandleMenu();
- decoration.setButtonVisibility();
+ decoration.setButtonVisibility(false);
}
}
@@ -299,8 +307,13 @@
*/
private void handleEventForMove(MotionEvent e) {
RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
- if (mDesktopModeController.isPresent()
- && mDesktopModeController.get().getDisplayAreaWindowingMode(taskInfo.displayId)
+ if (DesktopModeStatus.isProto2Enabled()
+ && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
+ return;
+ }
+ if (DesktopModeStatus.isProto1Enabled() && mDesktopModeController.isPresent()
+ && mDesktopModeController.get().getDisplayAreaWindowingMode(
+ taskInfo.displayId)
== WINDOWING_MODE_FULLSCREEN) {
return;
}
@@ -324,9 +337,20 @@
.stableInsets().top;
mDragResizeCallback.onDragResizeEnd(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
- if (e.getRawY(dragPointerIdx) <= statusBarHeight
- && DesktopModeStatus.isActive(mContext)) {
- mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false));
+ if (e.getRawY(dragPointerIdx) <= statusBarHeight) {
+ if (DesktopModeStatus.isProto2Enabled()) {
+ if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+ // Switch a single task to fullscreen
+ mDesktopTasksController.ifPresent(
+ c -> c.moveToFullscreen(taskInfo));
+ }
+ } else if (DesktopModeStatus.isProto1Enabled()) {
+ if (DesktopModeStatus.isActive(mContext)) {
+ // Turn off desktop mode
+ mDesktopModeController.ifPresent(
+ c -> c.setDesktopModeActive(false));
+ }
+ }
}
break;
}
@@ -408,13 +432,27 @@
* @param ev the {@link MotionEvent} received by {@link EventReceiver}
*/
private void handleReceivedMotionEvent(MotionEvent ev, InputMonitor inputMonitor) {
- if (!DesktopModeStatus.isActive(mContext)) {
- handleCaptionThroughStatusBar(ev);
+ if (DesktopModeStatus.isProto2Enabled()) {
+ CaptionWindowDecoration focusedDecor = getFocusedDecor();
+ if (focusedDecor == null
+ || focusedDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
+ handleCaptionThroughStatusBar(ev);
+ }
+ } else if (DesktopModeStatus.isProto1Enabled()) {
+ if (!DesktopModeStatus.isActive(mContext)) {
+ handleCaptionThroughStatusBar(ev);
+ }
}
handleEventOutsideFocusedCaption(ev);
// Prevent status bar from reacting to a caption drag.
- if (mTransitionDragActive && !DesktopModeStatus.isActive(mContext)) {
- inputMonitor.pilferPointers();
+ if (DesktopModeStatus.isProto2Enabled()) {
+ if (mTransitionDragActive) {
+ inputMonitor.pilferPointers();
+ }
+ } else if (DesktopModeStatus.isProto1Enabled()) {
+ if (mTransitionDragActive && !DesktopModeStatus.isActive(mContext)) {
+ inputMonitor.pilferPointers();
+ }
}
}
@@ -443,9 +481,20 @@
case MotionEvent.ACTION_DOWN: {
// Begin drag through status bar if applicable.
CaptionWindowDecoration focusedDecor = getFocusedDecor();
- if (focusedDecor != null && !DesktopModeStatus.isActive(mContext)
- && focusedDecor.checkTouchEventInHandle(ev)) {
- mTransitionDragActive = true;
+ if (focusedDecor != null) {
+ boolean dragFromStatusBarAllowed = false;
+ if (DesktopModeStatus.isProto2Enabled()) {
+ // In proto2 any full screen task can be dragged to freeform
+ dragFromStatusBarAllowed = focusedDecor.mTaskInfo.getWindowingMode()
+ == WINDOWING_MODE_FULLSCREEN;
+ } else if (DesktopModeStatus.isProto1Enabled()) {
+ // In proto1 task can be dragged to freeform when not in desktop mode
+ dragFromStatusBarAllowed = !DesktopModeStatus.isActive(mContext);
+ }
+
+ if (dragFromStatusBarAllowed && focusedDecor.checkTouchEventInHandle(ev)) {
+ mTransitionDragActive = true;
+ }
}
break;
}
@@ -460,7 +509,13 @@
int statusBarHeight = mDisplayController
.getDisplayLayout(focusedDecor.mTaskInfo.displayId).stableInsets().top;
if (ev.getY() > statusBarHeight) {
- mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
+ if (DesktopModeStatus.isProto2Enabled()) {
+ mDesktopTasksController.ifPresent(
+ c -> c.moveToDesktop(focusedDecor.mTaskInfo));
+ } else if (DesktopModeStatus.isProto1Enabled()) {
+ mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
+ }
+
return;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 037ca20..f7c7a87 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -16,8 +16,9 @@
package com.android.wm.shell.windowdecor;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
import android.app.ActivityManager;
-import android.app.WindowConfiguration;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -117,7 +118,7 @@
? R.dimen.freeform_decor_shadow_focused_thickness
: R.dimen.freeform_decor_shadow_unfocused_thickness;
final boolean isFreeform =
- taskInfo.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM;
+ taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM;
final boolean isDragResizeable = isFreeform && taskInfo.isResizeable;
WindowDecorLinearLayout oldRootView = mResult.mRootView;
@@ -167,11 +168,17 @@
// If this task is not focused, do not show caption.
setCaptionVisibility(mTaskInfo.isFocused);
- // Only handle should show if Desktop Mode is inactive.
- boolean desktopCurrentStatus = DesktopModeStatus.isActive(mContext);
- if (mDesktopActive != desktopCurrentStatus && mTaskInfo.isFocused) {
- mDesktopActive = desktopCurrentStatus;
- setButtonVisibility();
+ if (mTaskInfo.isFocused) {
+ if (DesktopModeStatus.isProto2Enabled()) {
+ updateButtonVisibility();
+ } else if (DesktopModeStatus.isProto1Enabled()) {
+ // Only handle should show if Desktop Mode is inactive.
+ boolean desktopCurrentStatus = DesktopModeStatus.isActive(mContext);
+ if (mDesktopActive != desktopCurrentStatus) {
+ mDesktopActive = desktopCurrentStatus;
+ setButtonVisibility(mDesktopActive);
+ }
+ }
}
if (!isDragResizeable) {
@@ -214,7 +221,7 @@
View handle = caption.findViewById(R.id.caption_handle);
handle.setOnTouchListener(mOnCaptionTouchListener);
handle.setOnClickListener(mOnCaptionButtonClickListener);
- setButtonVisibility();
+ updateButtonVisibility();
}
private void setupHandleMenu() {
@@ -244,14 +251,25 @@
/**
* Sets the visibility of buttons and color of caption based on desktop mode status
*/
- void setButtonVisibility() {
- mDesktopActive = DesktopModeStatus.isActive(mContext);
- int v = mDesktopActive ? View.VISIBLE : View.GONE;
+ void updateButtonVisibility() {
+ if (DesktopModeStatus.isProto2Enabled()) {
+ setButtonVisibility(mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM);
+ } else if (DesktopModeStatus.isProto1Enabled()) {
+ mDesktopActive = DesktopModeStatus.isActive(mContext);
+ setButtonVisibility(mDesktopActive);
+ }
+ }
+
+ /**
+ * Show or hide buttons
+ */
+ void setButtonVisibility(boolean visible) {
+ int visibility = visible ? View.VISIBLE : View.GONE;
View caption = mResult.mRootView.findViewById(R.id.caption);
View back = caption.findViewById(R.id.back_button);
View close = caption.findViewById(R.id.close_window);
- back.setVisibility(v);
- close.setVisibility(v);
+ back.setVisibility(visibility);
+ close.setVisibility(visibility);
int buttonTintColorRes =
mDesktopActive ? R.color.decor_button_dark_color
: R.color.decor_button_light_color;
@@ -260,7 +278,7 @@
View handle = caption.findViewById(R.id.caption_handle);
VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
handleBackground.setTintList(buttonTintColor);
- caption.getBackground().setTint(v == View.VISIBLE ? Color.WHITE : Color.TRANSPARENT);
+ caption.getBackground().setTint(visible ? Color.WHITE : Color.TRANSPARENT);
}
boolean isHandleMenuActive() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 9215496..7f85988 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -33,6 +33,7 @@
import android.view.ViewRootImpl;
import android.view.WindowManager;
import android.view.WindowlessWindowManager;
+import android.window.TaskConstants;
import android.window.WindowContainerTransaction;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -195,7 +196,9 @@
.setParent(mTaskSurface)
.build();
- startT.setTrustedOverlay(mDecorationContainerSurface, true);
+ startT.setTrustedOverlay(mDecorationContainerSurface, true)
+ .setLayer(mDecorationContainerSurface,
+ TaskConstants.TASK_CHILD_LAYER_WINDOW_DECORATIONS);
}
final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
@@ -213,8 +216,6 @@
outResult.mDecorContainerOffsetX, outResult.mDecorContainerOffsetY)
.setWindowCrop(mDecorationContainerSurface,
outResult.mWidth, outResult.mHeight)
- // TODO(b/244455401): Change the z-order when it's better organized
- .setLayer(mDecorationContainerSurface, mTaskInfo.numActivities + 1)
.show(mDecorationContainerSurface);
// TaskBackgroundSurface
@@ -225,6 +226,8 @@
.setEffectLayer()
.setParent(mTaskSurface)
.build();
+
+ startT.setLayer(mTaskBackgroundSurface, TaskConstants.TASK_CHILD_LAYER_TASK_BACKGROUND);
}
float shadowRadius = loadDimension(resources, params.mShadowRadiusId);
@@ -236,8 +239,6 @@
taskBounds.height())
.setShadowRadius(mTaskBackgroundSurface, shadowRadius)
.setColor(mTaskBackgroundSurface, mTmpColor)
- // TODO(b/244455401): Change the z-order when it's better organized
- .setLayer(mTaskBackgroundSurface, -1)
.show(mTaskBackgroundSurface);
// CaptionContainerSurface, CaptionWindowManager
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 1a8b954..2ac1dc0 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -69,6 +69,9 @@
enabled: false,
},
+ platform_apis: true,
+ certificate: "platform",
+
aaptflags: [
"--extra-packages",
"com.android.wm.shell.tests",
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
index 707c049..08af3d3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
@@ -16,8 +16,6 @@
package com.android.wm.shell.desktopmode;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -29,6 +27,9 @@
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask;
+import static com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask;
+import static com.android.wm.shell.desktopmode.DesktopTestHelpers.createHomeTask;
import static com.google.common.truth.Truth.assertThat;
@@ -48,7 +49,6 @@
import android.testing.AndroidTestingRunner;
import android.window.DisplayAreaInfo;
import android.window.TransitionRequestInfo;
-import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import android.window.WindowContainerTransaction.Change;
import android.window.WindowContainerTransaction.HierarchyOp;
@@ -59,7 +59,6 @@
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.sysui.ShellController;
@@ -355,7 +354,7 @@
@Test
public void testHandleTransitionRequest_taskOpen_returnsWct() {
RunningTaskInfo trigger = new RunningTaskInfo();
- trigger.token = new MockToken().mToken;
+ trigger.token = new MockToken().token();
trigger.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
WindowContainerTransaction wct = mController.handleRequest(
mock(IBinder.class),
@@ -366,7 +365,7 @@
@Test
public void testHandleTransitionRequest_taskToFront_returnsWct() {
RunningTaskInfo trigger = new RunningTaskInfo();
- trigger.token = new MockToken().mToken;
+ trigger.token = new MockToken().token();
trigger.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
WindowContainerTransaction wct = mController.handleRequest(
mock(IBinder.class),
@@ -381,40 +380,13 @@
}
private DisplayAreaInfo createMockDisplayArea() {
- DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(new MockToken().mToken,
+ DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(new MockToken().token(),
mContext.getDisplayId(), 0);
when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId()))
.thenReturn(displayAreaInfo);
return displayAreaInfo;
}
- private RunningTaskInfo createFreeformTask() {
- return new TestRunningTaskInfoBuilder()
- .setToken(new MockToken().token())
- .setActivityType(ACTIVITY_TYPE_STANDARD)
- .setWindowingMode(WINDOWING_MODE_FREEFORM)
- .setLastActiveTime(100)
- .build();
- }
-
- private RunningTaskInfo createFullscreenTask() {
- return new TestRunningTaskInfoBuilder()
- .setToken(new MockToken().token())
- .setActivityType(ACTIVITY_TYPE_STANDARD)
- .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
- .setLastActiveTime(100)
- .build();
- }
-
- private RunningTaskInfo createHomeTask() {
- return new TestRunningTaskInfoBuilder()
- .setToken(new MockToken().token())
- .setActivityType(ACTIVITY_TYPE_HOME)
- .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
- .setLastActiveTime(100)
- .build();
- }
-
private WindowContainerTransaction getDesktopModeSwitchTransaction() {
ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass(
WindowContainerTransaction.class);
@@ -442,18 +414,4 @@
assertThat(change.getConfiguration().windowConfiguration.getBounds().isEmpty()).isTrue();
}
- private static class MockToken {
- private final WindowContainerToken mToken;
- private final IBinder mBinder;
-
- MockToken() {
- mToken = mock(WindowContainerToken.class);
- mBinder = mock(IBinder.class);
- when(mToken.asBinder()).thenReturn(mBinder);
- }
-
- WindowContainerToken token() {
- return mToken;
- }
- }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
new file mode 100644
index 0000000..9a92879
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
+import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
+import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
+import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
+import android.os.Binder
+import android.testing.AndroidTestingRunner
+import android.view.WindowManager
+import android.view.WindowManager.TRANSIT_OPEN
+import android.view.WindowManager.TRANSIT_TO_FRONT
+import android.window.TransitionRequestInfo
+import android.window.WindowContainerTransaction
+import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER
+import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
+import com.android.dx.mockito.inline.extended.ExtendedMockito.never
+import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeTask
+import com.android.wm.shell.sysui.ShellController
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.isNull
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.any
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DesktopTasksControllerTest : ShellTestCase() {
+
+ @Mock lateinit var testExecutor: ShellExecutor
+ @Mock lateinit var shellController: ShellController
+ @Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer
+ @Mock lateinit var transitions: Transitions
+
+ lateinit var mockitoSession: StaticMockitoSession
+ lateinit var controller: DesktopTasksController
+ lateinit var shellInit: ShellInit
+ lateinit var desktopModeTaskRepository: DesktopModeTaskRepository
+
+ // Mock running tasks are registered here so we can get the list from mock shell task organizer
+ private val runningTasks = mutableListOf<RunningTaskInfo>()
+
+ @Before
+ fun setUp() {
+ mockitoSession = mockitoSession().mockStatic(DesktopModeStatus::class.java).startMocking()
+ whenever(DesktopModeStatus.isProto2Enabled()).thenReturn(true)
+
+ shellInit = Mockito.spy(ShellInit(testExecutor))
+ desktopModeTaskRepository = DesktopModeTaskRepository()
+
+ whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks }
+ whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() }
+
+ controller = createController()
+
+ shellInit.init()
+ }
+
+ private fun createController(): DesktopTasksController {
+ return DesktopTasksController(
+ context,
+ shellInit,
+ shellController,
+ shellTaskOrganizer,
+ transitions,
+ desktopModeTaskRepository,
+ TestShellExecutor()
+ )
+ }
+
+ @After
+ fun tearDown() {
+ mockitoSession.finishMocking()
+
+ runningTasks.clear()
+ }
+
+ @Test
+ fun instantiate_addInitCallback() {
+ verify(shellInit).addInitCallback(any(), any<DesktopTasksController>())
+ }
+
+ @Test
+ fun instantiate_flagOff_doNotAddInitCallback() {
+ whenever(DesktopModeStatus.isProto2Enabled()).thenReturn(false)
+ clearInvocations(shellInit)
+
+ createController()
+
+ verify(shellInit, never()).addInitCallback(any(), any<DesktopTasksController>())
+ }
+
+ @Test
+ fun showDesktopApps_allAppsInvisible_bringsToFront() {
+ val homeTask = setUpHomeTask()
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ markTaskHidden(task1)
+ markTaskHidden(task2)
+
+ controller.showDesktopApps()
+
+ val wct = getLatestWct()
+ assertThat(wct.hierarchyOps).hasSize(3)
+ // Expect order to be from bottom: home, task1, task2
+ wct.assertReorderAt(index = 0, homeTask)
+ wct.assertReorderAt(index = 1, task1)
+ wct.assertReorderAt(index = 2, task2)
+ }
+
+ @Test
+ fun showDesktopApps_appsAlreadyVisible_doesNothing() {
+ setUpHomeTask()
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ markTaskVisible(task1)
+ markTaskVisible(task2)
+
+ controller.showDesktopApps()
+
+ verifyWCTNotExecuted()
+ }
+
+ @Test
+ fun showDesktopApps_someAppsInvisible_reordersAll() {
+ val homeTask = setUpHomeTask()
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+ markTaskHidden(task1)
+ markTaskVisible(task2)
+
+ controller.showDesktopApps()
+
+ val wct = getLatestWct()
+ assertThat(wct.hierarchyOps).hasSize(3)
+ // Expect order to be from bottom: home, task1, task2
+ wct.assertReorderAt(index = 0, homeTask)
+ wct.assertReorderAt(index = 1, task1)
+ wct.assertReorderAt(index = 2, task2)
+ }
+
+ @Test
+ fun showDesktopApps_noActiveTasks_reorderHomeToTop() {
+ val homeTask = setUpHomeTask()
+
+ controller.showDesktopApps()
+
+ val wct = getLatestWct()
+ assertThat(wct.hierarchyOps).hasSize(1)
+ wct.assertReorderAt(index = 0, homeTask)
+ }
+
+ @Test
+ fun moveToDesktop() {
+ val task = setUpFullscreenTask()
+ controller.moveToDesktop(task)
+ val wct = getLatestWct()
+ assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_FREEFORM)
+ }
+
+ @Test
+ fun moveToDesktop_nonExistentTask_doesNothing() {
+ controller.moveToDesktop(999)
+ verifyWCTNotExecuted()
+ }
+
+ @Test
+ fun moveToFullscreen() {
+ val task = setUpFreeformTask()
+ controller.moveToFullscreen(task)
+ val wct = getLatestWct()
+ assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_FULLSCREEN)
+ }
+
+ @Test
+ fun moveToFullscreen_nonExistentTask_doesNothing() {
+ controller.moveToFullscreen(999)
+ verifyWCTNotExecuted()
+ }
+
+ @Test
+ fun getTaskWindowingMode() {
+ val fullscreenTask = setUpFullscreenTask()
+ val freeformTask = setUpFreeformTask()
+
+ assertThat(controller.getTaskWindowingMode(fullscreenTask.taskId))
+ .isEqualTo(WINDOWING_MODE_FULLSCREEN)
+ assertThat(controller.getTaskWindowingMode(freeformTask.taskId))
+ .isEqualTo(WINDOWING_MODE_FREEFORM)
+ assertThat(controller.getTaskWindowingMode(999)).isEqualTo(WINDOWING_MODE_UNDEFINED)
+ }
+
+ @Test
+ fun handleRequest_fullscreenTask_freeformVisible_returnSwitchToFreeformWCT() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+ val freeformTask = setUpFreeformTask()
+ markTaskVisible(freeformTask)
+ val fullscreenTask = createFullscreenTask()
+
+ val result = controller.handleRequest(Binder(), createTransition(fullscreenTask))
+ assertThat(result?.changes?.get(fullscreenTask.token.asBinder())?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_FREEFORM)
+ }
+
+ @Test
+ fun handleRequest_fullscreenTask_freeformNotVisible_returnNull() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+ val freeformTask = setUpFreeformTask()
+ markTaskHidden(freeformTask)
+ val fullscreenTask = createFullscreenTask()
+ assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull()
+ }
+
+ @Test
+ fun handleRequest_fullscreenTask_noOtherTasks_returnNull() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+ val fullscreenTask = createFullscreenTask()
+ assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull()
+ }
+
+ @Test
+ fun handleRequest_freeformTask_freeformVisible_returnNull() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+ val freeformTask1 = setUpFreeformTask()
+ markTaskVisible(freeformTask1)
+
+ val freeformTask2 = createFreeformTask()
+ assertThat(controller.handleRequest(Binder(), createTransition(freeformTask2))).isNull()
+ }
+
+ @Test
+ fun handleRequest_freeformTask_freeformNotVisible_returnSwitchToFullscreenWCT() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+ val freeformTask1 = setUpFreeformTask()
+ markTaskHidden(freeformTask1)
+
+ val freeformTask2 = createFreeformTask()
+ val result =
+ controller.handleRequest(
+ Binder(),
+ createTransition(freeformTask2, type = TRANSIT_TO_FRONT)
+ )
+ assertThat(result?.changes?.get(freeformTask2.token.asBinder())?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_FULLSCREEN)
+ }
+
+ @Test
+ fun handleRequest_freeformTask_noOtherTasks_returnSwitchToFullscreenWCT() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+ val task = createFreeformTask()
+ val result = controller.handleRequest(Binder(), createTransition(task))
+ assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_FULLSCREEN)
+ }
+
+ @Test
+ fun handleRequest_notOpenOrToFrontTransition_returnNull() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+ val task =
+ TestRunningTaskInfoBuilder()
+ .setActivityType(ACTIVITY_TYPE_STANDARD)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+ .build()
+ val transition = createTransition(task = task, type = WindowManager.TRANSIT_CLOSE)
+ val result = controller.handleRequest(Binder(), transition)
+ assertThat(result).isNull()
+ }
+
+ @Test
+ fun handleRequest_noTriggerTask_returnNull() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+ assertThat(controller.handleRequest(Binder(), createTransition(task = null))).isNull()
+ }
+
+ @Test
+ fun handleRequest_triggerTaskNotStandard_returnNull() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+ val task = TestRunningTaskInfoBuilder().setActivityType(ACTIVITY_TYPE_HOME).build()
+ assertThat(controller.handleRequest(Binder(), createTransition(task))).isNull()
+ }
+
+ @Test
+ fun handleRequest_triggerTaskNotFullscreenOrFreeform_returnNull() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+ val task =
+ TestRunningTaskInfoBuilder()
+ .setActivityType(ACTIVITY_TYPE_STANDARD)
+ .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW)
+ .build()
+ assertThat(controller.handleRequest(Binder(), createTransition(task))).isNull()
+ }
+
+ private fun setUpFreeformTask(): RunningTaskInfo {
+ val task = createFreeformTask()
+ whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
+ desktopModeTaskRepository.addActiveTask(task.taskId)
+ desktopModeTaskRepository.addOrMoveFreeformTaskToTop(task.taskId)
+ runningTasks.add(task)
+ return task
+ }
+
+ private fun setUpHomeTask(): RunningTaskInfo {
+ val task = createHomeTask()
+ whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
+ runningTasks.add(task)
+ return task
+ }
+
+ private fun setUpFullscreenTask(): RunningTaskInfo {
+ val task = createFullscreenTask()
+ whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
+ runningTasks.add(task)
+ return task
+ }
+
+ private fun markTaskVisible(task: RunningTaskInfo) {
+ desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = true)
+ }
+
+ private fun markTaskHidden(task: RunningTaskInfo) {
+ desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = false)
+ }
+
+ private fun getLatestWct(): WindowContainerTransaction {
+ val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
+ if (ENABLE_SHELL_TRANSITIONS) {
+ verify(transitions).startTransition(anyInt(), arg.capture(), isNull())
+ } else {
+ verify(shellTaskOrganizer).applyTransaction(arg.capture())
+ }
+ return arg.value
+ }
+
+ private fun verifyWCTNotExecuted() {
+ if (ENABLE_SHELL_TRANSITIONS) {
+ verify(transitions, never()).startTransition(anyInt(), any(), isNull())
+ } else {
+ verify(shellTaskOrganizer, never()).applyTransaction(any())
+ }
+ }
+
+ private fun createTransition(
+ task: RunningTaskInfo?,
+ @WindowManager.TransitionType type: Int = TRANSIT_OPEN
+ ): TransitionRequestInfo {
+ return TransitionRequestInfo(type, task, null /* remoteTransition */)
+ }
+}
+
+private fun WindowContainerTransaction.assertReorderAt(index: Int, task: RunningTaskInfo) {
+ assertWithMessage("WCT does not have a hierarchy operation at index $index")
+ .that(hierarchyOps.size)
+ .isGreaterThan(index)
+ val op = hierarchyOps[index]
+ assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER)
+ assertThat(op.container).isEqualTo(task.token.asBinder())
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
new file mode 100644
index 0000000..dc91d75
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
+import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
+import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+
+class DesktopTestHelpers {
+ companion object {
+ /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */
+ @JvmStatic
+ fun createFreeformTask(): RunningTaskInfo {
+ return TestRunningTaskInfoBuilder()
+ .setToken(MockToken().token())
+ .setActivityType(ACTIVITY_TYPE_STANDARD)
+ .setWindowingMode(WINDOWING_MODE_FREEFORM)
+ .setLastActiveTime(100)
+ .build()
+ }
+
+ /** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
+ @JvmStatic
+ fun createFullscreenTask(): RunningTaskInfo {
+ return TestRunningTaskInfoBuilder()
+ .setToken(MockToken().token())
+ .setActivityType(ACTIVITY_TYPE_STANDARD)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+ .setLastActiveTime(100)
+ .build()
+ }
+
+ /** Create a new home task */
+ @JvmStatic
+ fun createHomeTask(): RunningTaskInfo {
+ return TestRunningTaskInfoBuilder()
+ .setToken(MockToken().token())
+ .setActivityType(ACTIVITY_TYPE_HOME)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+ .setLastActiveTime(100)
+ .build()
+ }
+ }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/MockToken.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/MockToken.java
new file mode 100644
index 0000000..09d474d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/MockToken.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.os.IBinder;
+import android.window.WindowContainerToken;
+
+/**
+ * {@link WindowContainerToken} wrapper that supports a mock binder
+ */
+class MockToken {
+ private final WindowContainerToken mToken;
+
+ MockToken() {
+ mToken = mock(WindowContainerToken.class);
+ IBinder binder = mock(IBinder.class);
+ when(mToken.asBinder()).thenReturn(binder);
+ }
+
+ WindowContainerToken token() {
+ return mToken;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 3569860..65e1ea8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -155,7 +155,7 @@
final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
// Verify move to undefined stage while split screen not activated moves task to side stage.
- when(mMainStage.isActive()).thenReturn(false);
+ when(mStageCoordinator.isSplitScreenVisible()).thenReturn(false);
mStageCoordinator.setSideStagePosition(SPLIT_POSITION_TOP_OR_LEFT, null);
mStageCoordinator.moveToStage(task, STAGE_TYPE_UNDEFINED, SPLIT_POSITION_BOTTOM_OR_RIGHT,
new WindowContainerTransaction());
@@ -163,7 +163,7 @@
assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
// Verify move to undefined stage after split screen activated moves task based on position.
- when(mMainStage.isActive()).thenReturn(true);
+ when(mStageCoordinator.isSplitScreenVisible()).thenReturn(true);
assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
mStageCoordinator.moveToStage(task, STAGE_TYPE_UNDEFINED, SPLIT_POSITION_TOP_OR_LEFT,
new WindowContainerTransaction());
@@ -262,7 +262,7 @@
@Test
public void testResolveStartStage_afterSplitActivated_retrievesStagePosition() {
- when(mMainStage.isActive()).thenReturn(true);
+ when(mStageCoordinator.isSplitScreenVisible()).thenReturn(true);
mStageCoordinator.setSideStagePosition(SPLIT_POSITION_TOP_OR_LEFT, null /* wct */);
mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, SPLIT_POSITION_TOP_OR_LEFT,
@@ -320,4 +320,16 @@
assertTrue(options.getBoolean(
KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION));
}
+
+ @Test
+ public void testExitSplitScreenAfterFolded() {
+ when(mMainStage.isActive()).thenReturn(true);
+ when(mMainStage.isFocused()).thenReturn(true);
+ when(mMainStage.getTopVisibleChildTaskId()).thenReturn(INVALID_TASK_ID);
+
+ mStageCoordinator.onFoldedStateChanged(true);
+
+ verify(mStageCoordinator).onSplitScreenExit();
+ verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModelTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModelTests.java
index 0dbf30d..4875832 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModelTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModelTests.java
@@ -48,6 +48,7 @@
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.DesktopModeController;
+import com.android.wm.shell.desktopmode.DesktopTasksController;
import org.junit.Before;
import org.junit.Test;
@@ -74,6 +75,7 @@
@Mock private DisplayController mDisplayController;
@Mock private SyncTransactionQueue mSyncQueue;
@Mock private DesktopModeController mDesktopModeController;
+ @Mock private DesktopTasksController mDesktopTasksController;
@Mock private InputMonitor mInputMonitor;
@Mock private InputManager mInputManager;
@@ -95,6 +97,7 @@
mDisplayController,
mSyncQueue,
Optional.of(mDesktopModeController),
+ Optional.of(mDesktopTasksController),
mCaptionWindowDecorFactory,
mMockInputMonitorFactory
);
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index 9f52bf1..308bb3e 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -100,6 +100,8 @@
private final Object mListenerLock = new Object();
private OnImageReleasedListener mListener;
private ListenerHandler mListenerHandler;
+ private final Object mCloseLock = new Object();
+ private boolean mIsWriterValid = false;
private long mNativeContext;
private int mWidth;
@@ -305,6 +307,8 @@
ImageUtils.getEstimatedNativeAllocBytes(mWidth, mHeight,
useLegacyImageFormat ? imageFormat : hardwareBufferFormat, /*buffer count*/ 1);
VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes);
+
+ mIsWriterValid = true;
}
private ImageWriter(Surface surface, int maxImages, boolean useSurfaceImageFormatInfo,
@@ -448,14 +452,17 @@
* @see Image#close
*/
public Image dequeueInputImage() {
- if (mDequeuedImages.size() >= mMaxImages) {
- throw new IllegalStateException("Already dequeued max number of Images " + mMaxImages);
+ synchronized (mCloseLock) {
+ if (mDequeuedImages.size() >= mMaxImages) {
+ throw new IllegalStateException(
+ "Already dequeued max number of Images " + mMaxImages);
+ }
+ WriterSurfaceImage newImage = new WriterSurfaceImage(this);
+ nativeDequeueInputImage(mNativeContext, newImage);
+ mDequeuedImages.add(newImage);
+ newImage.mIsImageValid = true;
+ return newImage;
}
- WriterSurfaceImage newImage = new WriterSurfaceImage(this);
- nativeDequeueInputImage(mNativeContext, newImage);
- mDequeuedImages.add(newImage);
- newImage.mIsImageValid = true;
- return newImage;
}
/**
@@ -513,49 +520,53 @@
if (image == null) {
throw new IllegalArgumentException("image shouldn't be null");
}
- boolean ownedByMe = isImageOwnedByMe(image);
- if (ownedByMe && !(((WriterSurfaceImage) image).mIsImageValid)) {
- throw new IllegalStateException("Image from ImageWriter is invalid");
- }
- // For images from other components that have non-null owner, need to detach first,
- // then attach. Images without owners must already be attachable.
- if (!ownedByMe) {
- if ((image.getOwner() instanceof ImageReader)) {
- ImageReader prevOwner = (ImageReader) image.getOwner();
-
- prevOwner.detachImage(image);
- } else if (image.getOwner() != null) {
- throw new IllegalArgumentException("Only images from ImageReader can be queued to"
- + " ImageWriter, other image source is not supported yet!");
+ synchronized (mCloseLock) {
+ boolean ownedByMe = isImageOwnedByMe(image);
+ if (ownedByMe && !(((WriterSurfaceImage) image).mIsImageValid)) {
+ throw new IllegalStateException("Image from ImageWriter is invalid");
}
- attachAndQueueInputImage(image);
- // This clears the native reference held by the original owner.
- // When this Image is detached later by this ImageWriter, the
- // native memory won't be leaked.
- image.close();
- return;
- }
+ // For images from other components that have non-null owner, need to detach first,
+ // then attach. Images without owners must already be attachable.
+ if (!ownedByMe) {
+ if ((image.getOwner() instanceof ImageReader)) {
+ ImageReader prevOwner = (ImageReader) image.getOwner();
- Rect crop = image.getCropRect();
- nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), image.getDataSpace(),
- crop.left, crop.top, crop.right, crop.bottom, image.getTransform(),
- image.getScalingMode());
+ prevOwner.detachImage(image);
+ } else if (image.getOwner() != null) {
+ throw new IllegalArgumentException(
+ "Only images from ImageReader can be queued to"
+ + " ImageWriter, other image source is not supported yet!");
+ }
- /**
- * Only remove and cleanup the Images that are owned by this
- * ImageWriter. Images detached from other owners are only temporarily
- * owned by this ImageWriter and will be detached immediately after they
- * are released by downstream consumers, so there is no need to keep
- * track of them in mDequeuedImages.
- */
- if (ownedByMe) {
- mDequeuedImages.remove(image);
- // Do not call close here, as close is essentially cancel image.
- WriterSurfaceImage wi = (WriterSurfaceImage) image;
- wi.clearSurfacePlanes();
- wi.mIsImageValid = false;
+ attachAndQueueInputImage(image);
+ // This clears the native reference held by the original owner.
+ // When this Image is detached later by this ImageWriter, the
+ // native memory won't be leaked.
+ image.close();
+ return;
+ }
+
+ Rect crop = image.getCropRect();
+ nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), image.getDataSpace(),
+ crop.left, crop.top, crop.right, crop.bottom, image.getTransform(),
+ image.getScalingMode());
+
+ /**
+ * Only remove and cleanup the Images that are owned by this
+ * ImageWriter. Images detached from other owners are only temporarily
+ * owned by this ImageWriter and will be detached immediately after they
+ * are released by downstream consumers, so there is no need to keep
+ * track of them in mDequeuedImages.
+ */
+ if (ownedByMe) {
+ mDequeuedImages.remove(image);
+ // Do not call close here, as close is essentially cancel image.
+ WriterSurfaceImage wi = (WriterSurfaceImage) image;
+ wi.clearSurfacePlanes();
+ wi.mIsImageValid = false;
+ }
}
}
@@ -691,17 +702,23 @@
*/
@Override
public void close() {
- setOnImageReleasedListener(null, null);
- for (Image image : mDequeuedImages) {
- image.close();
- }
- mDequeuedImages.clear();
- nativeClose(mNativeContext);
- mNativeContext = 0;
+ synchronized (mCloseLock) {
+ if (!mIsWriterValid) {
+ return;
+ }
+ setOnImageReleasedListener(null, null);
+ for (Image image : mDequeuedImages) {
+ image.close();
+ }
+ mDequeuedImages.clear();
+ nativeClose(mNativeContext);
+ mNativeContext = 0;
- if (mEstimatedNativeAllocBytes > 0) {
- VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes);
- mEstimatedNativeAllocBytes = 0;
+ if (mEstimatedNativeAllocBytes > 0) {
+ VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes);
+ mEstimatedNativeAllocBytes = 0;
+ }
+ mIsWriterValid = false;
}
}
@@ -790,10 +807,16 @@
@Override
public void handleMessage(Message msg) {
OnImageReleasedListener listener;
- synchronized (mListenerLock) {
+ boolean isWriterValid;
+ synchronized (ImageWriter.this.mListenerLock) {
listener = mListener;
}
- if (listener != null) {
+ // Check to make sure we don't accidentally queue images after the writer is
+ // closed or closing
+ synchronized (ImageWriter.this.mCloseLock) {
+ isWriterValid = ImageWriter.this.mIsWriterValid;
+ }
+ if (listener != null && isWriterValid) {
listener.onImageReleased(ImageWriter.this);
}
}
@@ -813,10 +836,14 @@
}
final Handler handler;
+ final boolean isWriterValid;
synchronized (iw.mListenerLock) {
handler = iw.mListenerHandler;
}
- if (handler != null) {
+ synchronized (iw.mCloseLock) {
+ isWriterValid = iw.mIsWriterValid;
+ }
+ if (handler != null && isWriterValid) {
handler.sendEmptyMessage(0);
}
}
@@ -1050,6 +1077,9 @@
private int mTransform = 0; //Default no transform
private int mScalingMode = 0; //Default frozen scaling mode
+ private final Object mCloseLock = new Object(); // lock to protect against multiple
+ // simultaneous calls to close()
+
public WriterSurfaceImage(ImageWriter writer) {
mOwner = writer;
mWidth = writer.mWidth;
@@ -1192,8 +1222,10 @@
@Override
public void close() {
- if (mIsImageValid) {
- getOwner().abortImage(this);
+ synchronized (mCloseLock) {
+ if (mIsImageValid) {
+ getOwner().abortImage(this);
+ }
}
}
diff --git a/packages/BackupRestoreConfirmation/res/values-b+sr+Latn/strings.xml b/packages/BackupRestoreConfirmation/res/values-b+sr+Latn/strings.xml
index ab55120..e7bdd2f 100644
--- a/packages/BackupRestoreConfirmation/res/values-b+sr+Latn/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-b+sr+Latn/strings.xml
@@ -16,23 +16,23 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="backup_confirm_title" msgid="827563724209303345">"Rezervna kopije svih podataka"</string>
- <string name="restore_confirm_title" msgid="5469365809567486602">"Potpuno vraćanje"</string>
- <string name="backup_confirm_text" msgid="1878021282758896593">"Zahtevana je potpuna rezervna kopija svih podataka na povezani računar. Da li želite da dozvolite to?\n\nAko niste lično zahtevali rezervnu kopiju, ne dozvoljavajte nastavak radnje."</string>
- <string name="allow_backup_button_label" msgid="4217228747769644068">"Napravi rezervnu kopiju mojih podataka"</string>
- <string name="deny_backup_button_label" msgid="6009119115581097708">"Ne pravi rezervne kopije"</string>
- <string name="restore_confirm_text" msgid="7499866728030461776">"Zahtevano je potpuno vraćanje svih podataka sa povezanog računara. Da li želite da dozvolite to?\n\nAko niste lično zahtevali vraćanje, ne dozvoljavajte nastavak radnje. Time ćete zameniti sve podatke koji su trenutno na uređaju!"</string>
- <string name="allow_restore_button_label" msgid="3081286752277127827">"Vrati moje podatke"</string>
- <string name="deny_restore_button_label" msgid="1724367334453104378">"Ne vraćaj"</string>
- <string name="current_password_text" msgid="8268189555578298067">"Unesite trenutnu lozinku rezervne kopije u nastavku:"</string>
- <string name="device_encryption_restore_text" msgid="1570864916855208992">"Unesite lozinku uređaja za šifrovanje u nastavku."</string>
- <string name="device_encryption_backup_text" msgid="5866590762672844664">"Unesite lozinku uređaja za šifrovanje. Ovo će se koristiti i za šifrovanje rezervne arhive."</string>
- <string name="backup_enc_password_text" msgid="4981585714795233099">"Unesite lozinku koju ćete koristiti za šifrovanje podataka potpune rezervne kopije. Ako to polje ostavite prazno, koristiće se trenutna lozinka rezervne kopije:"</string>
- <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ako želite da šifrujete podatke potpune rezervne kopije, unesite lozinku u nastavku."</string>
- <string name="restore_enc_password_text" msgid="6140898525580710823">"Ako su podaci za vraćanje šifrovani, unesite lozinku u nastavku:"</string>
- <string name="toast_backup_started" msgid="550354281452756121">"Pokretanje pravljenja rezervne kopije..."</string>
- <string name="toast_backup_ended" msgid="3818080769548726424">"Rezervna kopija je napravljena"</string>
- <string name="toast_restore_started" msgid="7881679218971277385">"Pokretanje vraćanja..."</string>
- <string name="toast_restore_ended" msgid="1764041639199696132">"Vraćanje je završeno"</string>
- <string name="toast_timeout" msgid="5276598587087626877">"Vreme za radnju je isteklo"</string>
+ <string name="backup_confirm_title" msgid="827563724209303345">"Резервна копије свих података"</string>
+ <string name="restore_confirm_title" msgid="5469365809567486602">"Потпуно враћање"</string>
+ <string name="backup_confirm_text" msgid="1878021282758896593">"Захтевана је потпуна резервна копија свих података на повезани рачунар. Да ли желите да дозволите то?\n\nАко нисте лично захтевали резервну копију, не дозвољавајте наставак радње."</string>
+ <string name="allow_backup_button_label" msgid="4217228747769644068">"Направи резервну копију мојих података"</string>
+ <string name="deny_backup_button_label" msgid="6009119115581097708">"Не прави резервне копије"</string>
+ <string name="restore_confirm_text" msgid="7499866728030461776">"Захтевано је потпуно враћање свих података са повезаног рачунара. Да ли желите да дозволите то?\n\nАко нисте лично захтевали враћање, не дозвољавајте наставак радње. Тиме ћете заменити све податке који су тренутно на уређају!"</string>
+ <string name="allow_restore_button_label" msgid="3081286752277127827">"Врати моје податке"</string>
+ <string name="deny_restore_button_label" msgid="1724367334453104378">"Не враћај"</string>
+ <string name="current_password_text" msgid="8268189555578298067">"Унесите тренутну лозинку резервне копије у наставку:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Унесите лозинку уређаја за шифровање у наставку."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Унесите лозинку уређаја за шифровање. Ово ће се користити и за шифровање резервне архиве."</string>
+ <string name="backup_enc_password_text" msgid="4981585714795233099">"Унесите лозинку коју ћете користити за шифровање података потпуне резервне копије. Ако то поље оставите празно, користиће се тренутна лозинка резервне копије:"</string>
+ <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ако желите да шифрујете податке потпуне резервне копије, унесите лозинку у наставку."</string>
+ <string name="restore_enc_password_text" msgid="6140898525580710823">"Ако су подаци за враћање шифровани, унесите лозинку у наставку:"</string>
+ <string name="toast_backup_started" msgid="550354281452756121">"Покретање прављења резервне копије..."</string>
+ <string name="toast_backup_ended" msgid="3818080769548726424">"Резервна копија је направљена"</string>
+ <string name="toast_restore_started" msgid="7881679218971277385">"Покретање враћања..."</string>
+ <string name="toast_restore_ended" msgid="1764041639199696132">"Враћање је завршено"</string>
+ <string name="toast_timeout" msgid="5276598587087626877">"Време за радњу је истекло"</string>
</resources>
diff --git a/packages/CarrierDefaultApp/res/values-ar/strings.xml b/packages/CarrierDefaultApp/res/values-ar/strings.xml
index 0c67de7..ce118aa 100644
--- a/packages/CarrierDefaultApp/res/values-ar/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ar/strings.xml
@@ -8,9 +8,7 @@
<string name="portal_notification_detail" msgid="2295729385924660881">"النقر للانتقال إلى موقع %s الإلكتروني"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"يُرجى الاتصال بمقدم الخدمة %s"</string>
<string name="no_mobile_data_connection_title" msgid="7449525772416200578">"لا يوجد اتصال بيانات الجوال"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for no_mobile_data_connection (544980465184147010) -->
- <skip />
+ <string name="no_mobile_data_connection" msgid="544980465184147010">"إضافة بيانات أو خطة تجوال خلال %s"</string>
<string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"حالة بيانات الجوّال"</string>
<string name="action_bar_label" msgid="4290345990334377177">"تسجيل الدخول إلى شبكة الجوّال"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"الشبكة التي تحاول الانضمام إليها بها مشاكل أمنية."</string>
diff --git a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
index 5d55790..34c3bdc 100644
--- a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
@@ -2,16 +2,16 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
- <string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
- <string name="portal_notification_id" msgid="5155057562457079297">"Mobilni podaci su potrošeni"</string>
- <string name="no_data_notification_id" msgid="668400731803969521">"Mobilni podaci su deaktivirani"</string>
- <string name="portal_notification_detail" msgid="2295729385924660881">"Dodirnite da biste posetili veb-sajt %s"</string>
- <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontaktirajte dobavljača usluge %s"</string>
- <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nema veze za prenos podataka preko mobilnog operatera"</string>
- <string name="no_mobile_data_connection" msgid="544980465184147010">"Dodajte podatke ili paket za roming preko operatera %s"</string>
- <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status mobilnih podataka"</string>
- <string name="action_bar_label" msgid="4290345990334377177">"Prijavite se na mobilnu mrežu"</string>
- <string name="ssl_error_warning" msgid="3127935140338254180">"Mreža kojoj pokušavate da se pridružite ima bezbednosnih problema."</string>
- <string name="ssl_error_example" msgid="6188711843183058764">"Na primer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
- <string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko pregledača"</string>
+ <string name="android_system_label" msgid="2797790869522345065">"Мобилни оператер"</string>
+ <string name="portal_notification_id" msgid="5155057562457079297">"Мобилни подаци су потрошени"</string>
+ <string name="no_data_notification_id" msgid="668400731803969521">"Мобилни подаци су деактивирани"</string>
+ <string name="portal_notification_detail" msgid="2295729385924660881">"Додирните да бисте посетили веб-сајт %s"</string>
+ <string name="no_data_notification_detail" msgid="3112125343857014825">"Контактирајте добављача услуге %s"</string>
+ <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Нема везе за пренос података преко мобилног оператера"</string>
+ <string name="no_mobile_data_connection" msgid="544980465184147010">"Додајте податке или пакет за роминг преко оператера %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус мобилних података"</string>
+ <string name="action_bar_label" msgid="4290345990334377177">"Пријавите се на мобилну мрежу"</string>
+ <string name="ssl_error_warning" msgid="3127935140338254180">"Мрежа којој покушавате да се придружите има безбедносних проблема."</string>
+ <string name="ssl_error_example" msgid="6188711843183058764">"На пример, страница за пријављивање можда не припада приказаној организацији."</string>
+ <string name="ssl_error_continue" msgid="1138548463994095584">"Ипак настави преко прегледача"</string>
</resources>
diff --git a/packages/CarrierDefaultApp/res/values-te/strings.xml b/packages/CarrierDefaultApp/res/values-te/strings.xml
index 95c544a..42cbf1c 100644
--- a/packages/CarrierDefaultApp/res/values-te/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-te/strings.xml
@@ -13,5 +13,5 @@
<string name="action_bar_label" msgid="4290345990334377177">"మొబైల్ నెట్వర్క్కి సైన్ ఇన్ చేయండి"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"మీరు చేరడానికి ప్రయత్నిస్తున్న నెట్వర్క్ భద్రతా సమస్యలను కలిగి ఉంది."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ఉదాహరణకు, లాగిన్ పేజీ చూపిన సంస్థకు చెందినది కాకపోవచ్చు."</string>
- <string name="ssl_error_continue" msgid="1138548463994095584">"ఏదేమైనా బ్రౌజర్ ద్వారా కొనసాగించు"</string>
+ <string name="ssl_error_continue" msgid="1138548463994095584">"ఏదేమైనా బ్రౌజర్ ద్వారా కొనసాగించండి"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 75a4f1d..354ff2c 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -16,33 +16,33 @@
<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="4470785958457506021">"Menadžer pridruženog uređaja"</string>
- <string name="confirmation_title" msgid="3785000297483688997">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string>
- <string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
- <string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
- <string name="summary_watch" msgid="3002344206574997652">"Ova aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za interakciju sa obaveštenjima i pristup dozvolama za telefon, SMS, kontakte, kalendar, evidencije poziva i uređaje u blizini."</string>
- <string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string>
- <string name="permission_apps_summary" msgid="798718816711515431">"Strimujte aplikacije na telefonu"</string>
- <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama sa telefona"</string>
- <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string>
- <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
+ <string name="app_label" msgid="4470785958457506021">"Менаџер придруженог уређаја"</string>
+ <string name="confirmation_title" msgid="3785000297483688997">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа уређају <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string>
+ <string name="profile_name_watch" msgid="576290739483672360">"сат"</string>
+ <string name="chooser_title" msgid="2262294130493605839">"Одаберите профил <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
+ <string name="summary_watch" msgid="3002344206574997652">"Ова апликација је потребна за управљање уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ће добити дозволу за интеракцију са обавештењима и приступ дозволама за телефон, SMS, контакте, календар, евиденције позива и уређаје у близини."</string>
+ <string name="permission_apps" msgid="6142133265286656158">"Апликације"</string>
+ <string name="permission_apps_summary" msgid="798718816711515431">"Стримујте апликације на телефону"</string>
+ <string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа овим информацијама са телефона"</string>
+ <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
- <string name="title_computer" msgid="4693714143506569253">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama sa telefona"</string>
+ <string name="title_computer" msgid="4693714143506569253">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа овим информацијама са телефона"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
- <string name="permission_notification" msgid="693762568127741203">"Obaveštenja"</string>
- <string name="permission_notification_summary" msgid="884075314530071011">"Može da čita sva obaveštenja, uključujući informacije poput kontakata, poruka i slika"</string>
- <string name="permission_storage" msgid="6831099350839392343">"Slike i mediji"</string>
+ <string name="permission_notification" msgid="693762568127741203">"Обавештења"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Може да чита сва обавештења, укључујући информације попут контаката, порука и слика"</string>
+ <string name="permission_storage" msgid="6831099350839392343">"Слике и медији"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
- <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string>
- <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
+ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play услуге"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string>
+ <string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
- <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
- <string name="consent_no" msgid="2640796915611404382">"Ne dozvoli"</string>
- <string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
- <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prenesite dozvole za aplikacije na sat"</string>
- <string name="permission_sync_summary" msgid="8873391306499120778">"Da bismo pojednostavili podešavanje sata, aplikacije instalirane na satu tokom podešavanja će koristiti iste dozvole kao telefon.\n\n Te dozvole mogu da obuhvataju pristup mikrofonu i lokaciji sata."</string>
- <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string>
- <string name="vendor_header_button_description" msgid="6566660389500630608">"Dugme za više informacija"</string>
+ <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
+ <string name="consent_no" msgid="2640796915611404382">"Не дозволи"</string>
+ <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
+ <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Пренесите дозволе за апликације на сат"</string>
+ <string name="permission_sync_summary" msgid="8873391306499120778">"Да бисмо поједноставили подешавање сата, апликације инсталиране на сату током подешавања ће користити исте дозволе као телефон.\n\n Те дозволе могу да обухватају приступ микрофону и локацији сата."</string>
+ <string name="vendor_icon_description" msgid="4445875290032225965">"Икона апликације"</string>
+ <string name="vendor_header_button_description" msgid="6566660389500630608">"Дугме за више информација"</string>
</resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
index 0e770da..e0c6b2f 100644
--- a/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="keyguard_description" msgid="8582605799129954556">"Unesite lozinku i nastavite do dinamičnih ažuriranja sistema"</string>
- <string name="notification_install_completed" msgid="6252047868415172643">"Dinamični sistem je spreman. Da biste počeli da ga koristite, restartujte uređaj."</string>
- <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalira se"</string>
- <string name="notification_install_failed" msgid="4066039210317521404">"Instaliranje nije uspelo"</string>
- <string name="notification_image_validation_failed" msgid="2720357826403917016">"Validacija slike diska nije uspela. Otkažite instalaciju."</string>
- <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Trenutno je pokrenut dinamični sistem. Restartujte da biste koristili originalnu verziju Android-a."</string>
- <string name="notification_action_cancel" msgid="5929299408545961077">"Otkaži"</string>
- <string name="notification_action_discard" msgid="1817481003134947493">"Odbaci"</string>
- <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Restartuj"</string>
- <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restartuj"</string>
- <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamični sistem je odbačen"</string>
- <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Restartovanje ili učitavanje dinamičnog sistema nije uspelo"</string>
- <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Onemogućavanje dinamičnog sistema nije uspelo"</string>
+ <string name="keyguard_description" msgid="8582605799129954556">"Унесите лозинку и наставите до динамичних ажурирања система"</string>
+ <string name="notification_install_completed" msgid="6252047868415172643">"Динамични систем је спреман. Да бисте почели да га користите, рестартујте уређај."</string>
+ <string name="notification_install_inprogress" msgid="7383334330065065017">"Инсталира се"</string>
+ <string name="notification_install_failed" msgid="4066039210317521404">"Инсталирање није успело"</string>
+ <string name="notification_image_validation_failed" msgid="2720357826403917016">"Валидација слике диска није успела. Откажите инсталацију."</string>
+ <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Тренутно је покренут динамични систем. Рестартујте да бисте користили оригиналну верзију Android-а."</string>
+ <string name="notification_action_cancel" msgid="5929299408545961077">"Откажи"</string>
+ <string name="notification_action_discard" msgid="1817481003134947493">"Одбаци"</string>
+ <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Рестартуј"</string>
+ <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Рестартуј"</string>
+ <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамични систем је одбачен"</string>
+ <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Рестартовање или учитавање динамичног система није успело"</string>
+ <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Онемогућавање динамичног система није успело"</string>
</resources>
diff --git a/packages/InputDevices/res/values-b+sr+Latn/strings.xml b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
index 1fc84f3..973b833 100644
--- a/packages/InputDevices/res/values-b+sr+Latn/strings.xml
+++ b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
@@ -1,53 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="8016145283189546017">"Ulazni uređaji"</string>
- <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android tastatura"</string>
- <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"engleska (UK)"</string>
- <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"engleska (SAD)"</string>
- <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"engleska (SAD), međunarodni stil"</string>
- <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"engleska (SAD), Colemak stil"</string>
- <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"engleska (SAD), Dvorak stil"</string>
- <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"engleska (SAD), Workman stil"</string>
- <string name="keyboard_layout_german_label" msgid="8451565865467909999">"nemačka"</string>
- <string name="keyboard_layout_french_label" msgid="813450119589383723">"francuska"</string>
- <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"francuska (Kanada)"</string>
- <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ruska"</string>
- <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ruska, Mac stil"</string>
- <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"španska"</string>
- <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"švajcarsko francuska"</string>
- <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"švajcarsko nemačka"</string>
- <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belgijska"</string>
- <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bugarska"</string>
- <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"bugarska fonetska"</string>
- <string name="keyboard_layout_italian" msgid="6497079660449781213">"italijanska"</string>
- <string name="keyboard_layout_danish" msgid="8036432066627127851">"danska"</string>
- <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"norveška"</string>
- <string name="keyboard_layout_swedish" msgid="732959109088479351">"švedska"</string>
- <string name="keyboard_layout_finnish" msgid="5585659438924315466">"finska"</string>
- <string name="keyboard_layout_croatian" msgid="4172229471079281138">"hrvatska"</string>
- <string name="keyboard_layout_czech" msgid="1349256901452975343">"češka"</string>
- <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"Stil češke QWERTY tastature"</string>
- <string name="keyboard_layout_estonian" msgid="8775830985185665274">"estonska"</string>
- <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"mađarska"</string>
- <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"islandska"</string>
- <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brazilska"</string>
- <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugalska"</string>
- <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovačka"</string>
- <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovenačka"</string>
- <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turska"</string>
- <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"turska F"</string>
- <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinska"</string>
- <string name="keyboard_layout_arabic" msgid="5671970465174968712">"arapski"</string>
- <string name="keyboard_layout_greek" msgid="7289253560162386040">"grčki"</string>
- <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"hebrejski"</string>
- <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"litvanski"</string>
- <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"španski (Latinska Amerika)"</string>
- <string name="keyboard_layout_latvian" msgid="4405417142306250595">"letonski"</string>
- <string name="keyboard_layout_persian" msgid="3920643161015888527">"persijska"</string>
- <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"azerbejdžanska"</string>
- <string name="keyboard_layout_polish" msgid="1121588624094925325">"poljski"</string>
- <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"beloruski"</string>
- <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongolska"</string>
- <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzijska"</string>
+ <string name="app_label" msgid="8016145283189546017">"Улазни уређаји"</string>
+ <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android тастатура"</string>
+ <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"енглеска (УК)"</string>
+ <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"енглеска (САД)"</string>
+ <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"енглеска (САД), међународни стил"</string>
+ <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"енглеска (САД), Colemak стил"</string>
+ <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"енглеска (САД), Dvorak стил"</string>
+ <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"енглеска (САД), Workman стил"</string>
+ <string name="keyboard_layout_german_label" msgid="8451565865467909999">"немачка"</string>
+ <string name="keyboard_layout_french_label" msgid="813450119589383723">"француска"</string>
+ <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"француска (Канада)"</string>
+ <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"руска"</string>
+ <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"руска, Mac стил"</string>
+ <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"шпанска"</string>
+ <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"швајцарско француска"</string>
+ <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"швајцарско немачка"</string>
+ <string name="keyboard_layout_belgian" msgid="2011984572838651558">"белгијска"</string>
+ <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"бугарска"</string>
+ <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"бугарска фонетска"</string>
+ <string name="keyboard_layout_italian" msgid="6497079660449781213">"италијанска"</string>
+ <string name="keyboard_layout_danish" msgid="8036432066627127851">"данска"</string>
+ <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"норвешка"</string>
+ <string name="keyboard_layout_swedish" msgid="732959109088479351">"шведска"</string>
+ <string name="keyboard_layout_finnish" msgid="5585659438924315466">"финска"</string>
+ <string name="keyboard_layout_croatian" msgid="4172229471079281138">"хрватска"</string>
+ <string name="keyboard_layout_czech" msgid="1349256901452975343">"чешка"</string>
+ <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"Стил чешке QWERTY тастатуре"</string>
+ <string name="keyboard_layout_estonian" msgid="8775830985185665274">"естонска"</string>
+ <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"мађарска"</string>
+ <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"исландска"</string>
+ <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"бразилска"</string>
+ <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"португалска"</string>
+ <string name="keyboard_layout_slovak" msgid="2469379934672837296">"словачка"</string>
+ <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"словеначка"</string>
+ <string name="keyboard_layout_turkish" msgid="7736163250907964898">"турска"</string>
+ <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"турска F"</string>
+ <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"украјинска"</string>
+ <string name="keyboard_layout_arabic" msgid="5671970465174968712">"арапски"</string>
+ <string name="keyboard_layout_greek" msgid="7289253560162386040">"грчки"</string>
+ <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"хебрејски"</string>
+ <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"литвански"</string>
+ <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"шпански (Латинска Америка)"</string>
+ <string name="keyboard_layout_latvian" msgid="4405417142306250595">"летонски"</string>
+ <string name="keyboard_layout_persian" msgid="3920643161015888527">"персијска"</string>
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"азербејџанска"</string>
+ <string name="keyboard_layout_polish" msgid="1121588624094925325">"пољски"</string>
+ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"белоруски"</string>
+ <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"монголска"</string>
+ <string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузијска"</string>
</resources>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
index f646b20..d964d3f 100644
--- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
+++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
@@ -16,81 +16,81 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="7488448184431507488">"Program za instal. paketa"</string>
- <string name="install" msgid="711829760615509273">"Instaliraj"</string>
- <string name="update" msgid="3932142540719227615">"Ažuriraj"</string>
- <string name="done" msgid="6632441120016885253">"Gotovo"</string>
- <string name="cancel" msgid="1018267193425558088">"Otkaži"</string>
- <string name="installing" msgid="4921993079741206516">"Instalira se..."</string>
- <string name="installing_app" msgid="1165095864863849422">"Instalira se <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
- <string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
- <string name="install_confirm_question" msgid="7663733664476363311">"Želite da instalirate ovu aplikaciju?"</string>
- <string name="install_confirm_question_update" msgid="3348888852318388584">"Želite da ažurirate ovu aplikaciju?"</string>
- <string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
- <string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa je blokirano."</string>
- <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer je paket neusaglašen sa postojećim paketom."</string>
- <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikacija nije instalirana jer nije kompatibilna sa tabletom."</string>
- <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ova aplikacija nije kompatibilna sa TV-om."</string>
- <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikacija nije instalirana jer nije kompatibilna sa telefonom."</string>
- <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikacija nije instalirana jer je paket nevažeći."</string>
- <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na tablet."</string>
- <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na TV."</string>
- <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na telefon."</string>
- <string name="launch" msgid="3952550563999890101">"Otvori"</string>
- <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administrator ne dozvoljava instaliranje aplikacija dobijenih iz nepoznatih izvora"</string>
- <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ovaj korisnik ne može da instalira nepoznate aplikacije"</string>
- <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ovom korisniku nije dozvoljeno da instalira aplikacije"</string>
- <string name="ok" msgid="7871959885003339302">"Potvrdi"</string>
- <string name="manage_applications" msgid="5400164782453975580">"Upravljajte apl."</string>
- <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nema više prostora"</string>
- <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite prostor i probajte ponovo."</string>
- <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikacija nije pronađena"</string>
- <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikacija nije pronađena na listi instaliranih aplikacija."</string>
- <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nije dozvoljeno"</string>
- <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Aktuelnom korisniku nije dozvoljeno da obavi ovo deinstaliranje."</string>
- <string name="generic_error_dlg_title" msgid="5863195085927067752">"Greška"</string>
- <string name="generic_error_dlg_text" msgid="5287861443265795232">"Deinstaliranje aplikacije nije uspelo."</string>
- <string name="uninstall_application_title" msgid="4045420072401428123">"Deinstaliraj aplikaciju"</string>
- <string name="uninstall_update_title" msgid="824411791011583031">"Deinstaliraj ažuriranje"</string>
- <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je deo sledeće aplikacije:"</string>
- <string name="uninstall_application_text" msgid="3816830743706143980">"Želite da deinstalirate ovu aplikaciju?"</string>
- <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Da li želite da deinstalirate ovu aplikaciju za "<b>"sve"</b>" korisnike? Aplikacija i podaci uz nje biće uklonjeni za "<b>"sve"</b>" korisnike ovog uređaja."</string>
- <string name="uninstall_application_text_user" msgid="498072714173920526">"Želite li da deinstalirate ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
- <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Da li želite da deinstalirate ovu aplikaciju sa poslovnog profila?"</string>
- <string name="uninstall_update_text" msgid="863648314632448705">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni."</string>
- <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni. Ovo utiče na sve korisnike ovog uređaja, uključujući i one sa poslovnim profilima."</string>
- <string name="uninstall_keep_data" msgid="7002379587465487550">"Zadrži <xliff:g id="SIZE">%1$s</xliff:g> podataka aplikacije."</string>
- <string name="uninstalling_notification_channel" msgid="840153394325714653">"Aktivna deinstaliranja"</string>
- <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspela deinstaliranja"</string>
- <string name="uninstalling" msgid="8709566347688966845">"Deinstalira se…"</string>
- <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se deinstalira…"</string>
- <string name="uninstall_done" msgid="439354138387969269">"Deinstaliranje je završeno."</string>
- <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je deinstalirana"</string>
- <string name="uninstall_failed" msgid="1847750968168364332">"Deinstaliranje nije uspelo."</string>
- <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspelo."</string>
- <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja"</string>
- <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja za <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
- <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Ova aplikacija je obavezna za neke korisnike ili profile, a deinstalirana je za druge"</string>
- <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ova aplikacija je obavezna za vaš profil i ne može da se deinstalira."</string>
- <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ova aplikacija je obavezna za administratora uređaja i ne može da se deinstalira."</string>
- <string name="manage_device_administrators" msgid="3092696419363842816">"Upravljajte aplikacijama administratora uređaja"</string>
- <string name="manage_users" msgid="1243995386982560813">"Upravljajte korisnicima"</string>
- <string name="uninstall_failed_msg" msgid="2176744834786696012">"Nismo uspeli da deinstaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Došlo je do problema pri raščlanjivanju paketa."</string>
+ <string name="app_name" msgid="7488448184431507488">"Програм за инстал. пакета"</string>
+ <string name="install" msgid="711829760615509273">"Инсталирај"</string>
+ <string name="update" msgid="3932142540719227615">"Ажурирај"</string>
+ <string name="done" msgid="6632441120016885253">"Готово"</string>
+ <string name="cancel" msgid="1018267193425558088">"Откажи"</string>
+ <string name="installing" msgid="4921993079741206516">"Инсталира се..."</string>
+ <string name="installing_app" msgid="1165095864863849422">"Инсталира се <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="5987363587661783896">"Апликација је инсталирана."</string>
+ <string name="install_confirm_question" msgid="7663733664476363311">"Желите да инсталирате ову апликацију?"</string>
+ <string name="install_confirm_question_update" msgid="3348888852318388584">"Желите да ажурирате ову апликацију?"</string>
+ <string name="install_failed" msgid="5777824004474125469">"Апликација није инсталирана."</string>
+ <string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирање пакета је блокирано."</string>
+ <string name="install_failed_conflict" msgid="3493184212162521426">"Апликација није инсталирана јер је пакет неусаглашен са постојећим пакетом."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Апликација није инсталирана јер није компатибилна са таблетом."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ова апликација није компатибилна са ТВ-ом."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Апликација није инсталирана јер није компатибилна са телефоном."</string>
+ <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Апликација није инсталирана јер је пакет неважећи."</string>
+ <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на таблет."</string>
+ <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на ТВ."</string>
+ <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на телефон."</string>
+ <string name="launch" msgid="3952550563999890101">"Отвори"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Администратор не дозвољава инсталирање апликација добијених из непознатих извора"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Овај корисник не може да инсталира непознате апликације"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Овом кориснику није дозвољено да инсталира апликације"</string>
+ <string name="ok" msgid="7871959885003339302">"Потврди"</string>
+ <string name="manage_applications" msgid="5400164782453975580">"Управљајте апл."</string>
+ <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Нема више простора"</string>
+ <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>. Ослободите простор и пробајте поново."</string>
+ <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Апликација није пронађена"</string>
+ <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Апликација није пронађена на листи инсталираних апликација."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Није дозвољено"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Актуелном кориснику није дозвољено да обави ово деинсталирање."</string>
+ <string name="generic_error_dlg_title" msgid="5863195085927067752">"Грешка"</string>
+ <string name="generic_error_dlg_text" msgid="5287861443265795232">"Деинсталирање апликације није успело."</string>
+ <string name="uninstall_application_title" msgid="4045420072401428123">"Деинсталирај апликацију"</string>
+ <string name="uninstall_update_title" msgid="824411791011583031">"Деинсталирај ажурирање"</string>
+ <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> је део следеће апликације:"</string>
+ <string name="uninstall_application_text" msgid="3816830743706143980">"Желите да деинсталирате ову апликацију?"</string>
+ <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Да ли желите да деинсталирате ову апликацију за "<b>"све"</b>" кориснике? Апликација и подаци уз ње биће уклоњени за "<b>"све"</b>" кориснике овог уређаја."</string>
+ <string name="uninstall_application_text_user" msgid="498072714173920526">"Желите ли да деинсталирате ову апликацију за корисника <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Да ли желите да деинсталирате ову апликацију са пословног профила?"</string>
+ <string name="uninstall_update_text" msgid="863648314632448705">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени."</string>
+ <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени. Ово утиче на све кориснике овог уређаја, укључујући и оне са пословним профилима."</string>
+ <string name="uninstall_keep_data" msgid="7002379587465487550">"Задржи <xliff:g id="SIZE">%1$s</xliff:g> података апликације."</string>
+ <string name="uninstalling_notification_channel" msgid="840153394325714653">"Активна деинсталирања"</string>
+ <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Неуспела деинсталирања"</string>
+ <string name="uninstalling" msgid="8709566347688966845">"Деинсталира се…"</string>
+ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
+ <string name="uninstall_done" msgid="439354138387969269">"Деинсталирање је завршено."</string>
+ <string name="uninstall_done_app" msgid="4588850984473605768">"Апликација <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> је деинсталирана"</string>
+ <string name="uninstall_failed" msgid="1847750968168364332">"Деинсталирање није успело."</string>
+ <string name="uninstall_failed_app" msgid="5506028705017601412">"Деинсталирање апликације <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> није успело."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Не можете да деинсталирате апликацију за активног администратора уређаја"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Не можете да деинсталирате апликацију за активног администратора уређаја за <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Ова апликација је обавезна за неке кориснике или профиле, а деинсталирана је за друге"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ова апликација је обавезна за ваш профил и не може да се деинсталира."</string>
+ <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ова апликација је обавезна за администратора уређаја и не може да се деинсталира."</string>
+ <string name="manage_device_administrators" msgid="3092696419363842816">"Управљајте апликацијама администратора уређаја"</string>
+ <string name="manage_users" msgid="1243995386982560813">"Управљаjте корисницима"</string>
+ <string name="uninstall_failed_msg" msgid="2176744834786696012">"Нисмо успели да деинсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Дошло је до проблема при рашчлањивању пакета."</string>
<string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
- <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Radnje Instaliraj/Deinstaliraj nisu podržane u Wear-u."</string>
- <string name="message_staging" msgid="8032722385658438567">"Aplikacija se priprema…"</string>
- <string name="app_name_unknown" msgid="6881210203354323926">"Nepoznato"</string>
- <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Iz bezbednosnih razloga tabletu trenutno nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora. To možete da promenite u podešavanjima."</string>
- <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Iz bezbednosnih razloga televizoru trenutno nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora. To možete da promenite u podešavanjima."</string>
- <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Iz bezbednosnih razloga telefonu trenutno nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora. To možete da promenite u podešavanjima."</string>
- <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefon i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja telefona ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
- <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tablet i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja tableta ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
- <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja TV-a ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
- <string name="anonymous_source_continue" msgid="4375745439457209366">"Nastavi"</string>
- <string name="external_sources_settings" msgid="4046964413071713807">"Podešavanja"</string>
- <string name="wear_app_channel" msgid="1960809674709107850">"Instaliranje/deinstaliranje Wear aplikac."</string>
- <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Obaveštenje o instaliranju aplikacije"</string>
- <string name="notification_installation_success_message" msgid="6450467996056038442">"Instalirana je"</string>
- <string name="notification_installation_success_status" msgid="3172502643504323321">"Aplikacija „<xliff:g id="APPNAME">%1$s</xliff:g>“ je instalirana"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Радње Инсталирај/Деинсталирај нису подржане у Wear-у."</string>
+ <string name="message_staging" msgid="8032722385658438567">"Апликација се припрема…"</string>
+ <string name="app_name_unknown" msgid="6881210203354323926">"Непознато"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Из безбедносних разлога таблету тренутно није дозвољено да инсталира непознате апликације из овог извора. То можете да промените у подешавањима."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Из безбедносних разлога телевизору тренутно није дозвољено да инсталира непознате апликације из овог извора. То можете да промените у подешавањима."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Из безбедносних разлога телефону тренутно није дозвољено да инсталира непознате апликације из овог извора. То можете да промените у подешавањима."</string>
+ <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефон и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења телефона или губитак података до којих може да дође због њеног коришћења."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таблет и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења таблета или губитак података до којих може да дође због њеног коришћења."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ТВ и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења ТВ-а или губитак података до којих може да дође због њеног коришћења."</string>
+ <string name="anonymous_source_continue" msgid="4375745439457209366">"Настави"</string>
+ <string name="external_sources_settings" msgid="4046964413071713807">"Подешавања"</string>
+ <string name="wear_app_channel" msgid="1960809674709107850">"Инсталирање/деинсталирање Wear апликац."</string>
+ <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Обавештење о инсталирању апликације"</string>
+ <string name="notification_installation_success_message" msgid="6450467996056038442">"Инсталирана је"</string>
+ <string name="notification_installation_success_status" msgid="3172502643504323321">"Апликација „<xliff:g id="APPNAME">%1$s</xliff:g>“ је инсталирана"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
index 07615ae..bc29999 100644
--- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
+++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
@@ -16,98 +16,98 @@
<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="4469836075319831821">"Štampanje iz memorije"</string>
- <string name="more_options_button" msgid="2243228396432556771">"Još opcija"</string>
- <string name="label_destination" msgid="9132510997381599275">"Odredište"</string>
- <string name="label_copies" msgid="3634531042822968308">"Kopije"</string>
- <string name="label_copies_summary" msgid="3861966063536529540">"Kopija:"</string>
- <string name="label_paper_size" msgid="908654383827777759">"Veličina papira"</string>
- <string name="label_paper_size_summary" msgid="5668204981332138168">"Veličina papira:"</string>
- <string name="label_color" msgid="1108690305218188969">"Boja"</string>
- <string name="label_duplex" msgid="5370037254347072243">"Dvostrano"</string>
- <string name="label_orientation" msgid="2853142581990496477">"Položaj"</string>
- <string name="label_pages" msgid="7768589729282182230">"Stranice"</string>
- <string name="destination_default_text" msgid="5422708056807065710">"Izaberite štampač"</string>
- <string name="template_all_pages" msgid="3322235982020148762">"Sve stranice (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
- <string name="template_page_range" msgid="428638530038286328">"Opseg od <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
- <string name="pages_range_example" msgid="8558694453556945172">"npr. 1–5, 8, 11–13"</string>
- <string name="print_preview" msgid="8010217796057763343">"Pregled pre štampanja"</string>
- <string name="install_for_print_preview" msgid="6366303997385509332">"Instaliraj PDF prikazivač za pregled"</string>
- <string name="printing_app_crashed" msgid="854477616686566398">"Aplikacija za štampanje je otkazala"</string>
- <string name="generating_print_job" msgid="3119608742651698916">"Generisanje zadatka za štampanje"</string>
- <string name="save_as_pdf" msgid="5718454119847596853">"Sačuvaj kao PDF"</string>
- <string name="all_printers" msgid="5018829726861876202">"Svi štampači…"</string>
- <string name="print_dialog" msgid="32628687461331979">"Dijalog za štampanje"</string>
+ <string name="app_label" msgid="4469836075319831821">"Штампање из меморије"</string>
+ <string name="more_options_button" msgid="2243228396432556771">"Још опција"</string>
+ <string name="label_destination" msgid="9132510997381599275">"Одредиште"</string>
+ <string name="label_copies" msgid="3634531042822968308">"Копије"</string>
+ <string name="label_copies_summary" msgid="3861966063536529540">"Копија:"</string>
+ <string name="label_paper_size" msgid="908654383827777759">"Величина папира"</string>
+ <string name="label_paper_size_summary" msgid="5668204981332138168">"Величина папира:"</string>
+ <string name="label_color" msgid="1108690305218188969">"Боја"</string>
+ <string name="label_duplex" msgid="5370037254347072243">"Двострано"</string>
+ <string name="label_orientation" msgid="2853142581990496477">"Положај"</string>
+ <string name="label_pages" msgid="7768589729282182230">"Странице"</string>
+ <string name="destination_default_text" msgid="5422708056807065710">"Изаберите штампач"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Све странице (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Опсег од <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="pages_range_example" msgid="8558694453556945172">"нпр. 1–5, 8, 11–13"</string>
+ <string name="print_preview" msgid="8010217796057763343">"Преглед пре штампања"</string>
+ <string name="install_for_print_preview" msgid="6366303997385509332">"Инсталирај PDF приказивач за преглед"</string>
+ <string name="printing_app_crashed" msgid="854477616686566398">"Апликација за штампање је отказала"</string>
+ <string name="generating_print_job" msgid="3119608742651698916">"Генерисање задатка за штампање"</string>
+ <string name="save_as_pdf" msgid="5718454119847596853">"Сачувај као PDF"</string>
+ <string name="all_printers" msgid="5018829726861876202">"Сви штампачи…"</string>
+ <string name="print_dialog" msgid="32628687461331979">"Дијалог за штампање"</string>
<string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
- <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>. stranica od <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
- <string name="summary_template" msgid="8899734908625669193">"Rezime, kopije (<xliff:g id="COPIES">%1$s</xliff:g>), veličina papira <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
- <string name="expand_handle" msgid="7282974448109280522">"Regulator za širenje"</string>
- <string name="collapse_handle" msgid="6886637989442507451">"Regulator za skupljanje"</string>
- <string name="print_button" msgid="645164566271246268">"Štampaj"</string>
- <string name="savetopdf_button" msgid="2976186791686924743">"Sačuvaj u PDF-u"</string>
- <string name="print_options_expanded" msgid="6944679157471691859">"Opcije štampanja su proširene"</string>
- <string name="print_options_collapsed" msgid="7455930445670414332">"Opcije štampanja su skupljene"</string>
- <string name="search" msgid="5421724265322228497">"Pretraži"</string>
- <string name="all_printers_label" msgid="3178848870161526399">"Svi štampači"</string>
- <string name="add_print_service_label" msgid="5356702546188981940">"Dodaj uslugu"</string>
- <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Okvir za pretragu je prikazan"</string>
- <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Okvir za pretragu je sakriven"</string>
- <string name="print_add_printer" msgid="1088656468360653455">"Dodaj štampač"</string>
- <string name="print_select_printer" msgid="7388760939873368698">"Izaberi štampač"</string>
- <string name="print_forget_printer" msgid="5035287497291910766">"Zaboravi štampač"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>. страница од <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Резиме, копије (<xliff:g id="COPIES">%1$s</xliff:g>), величина папира <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Регулатор за ширење"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Регулатор за скупљање"</string>
+ <string name="print_button" msgid="645164566271246268">"Штампај"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"Сачувај у PDF-у"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Опције штампања су проширене"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Опције штампања су скупљене"</string>
+ <string name="search" msgid="5421724265322228497">"Претражи"</string>
+ <string name="all_printers_label" msgid="3178848870161526399">"Сви штампачи"</string>
+ <string name="add_print_service_label" msgid="5356702546188981940">"Додај услугу"</string>
+ <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Оквир за претрагу је приказан"</string>
+ <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Оквир за претрагу је сакривен"</string>
+ <string name="print_add_printer" msgid="1088656468360653455">"Додај штампач"</string>
+ <string name="print_select_printer" msgid="7388760939873368698">"Изабери штампач"</string>
+ <string name="print_forget_printer" msgid="5035287497291910766">"Заборави штампач"</string>
<plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
- <item quantity="one">Pronađen je <xliff:g id="COUNT_1">%1$s</xliff:g> štampač</item>
- <item quantity="few">Pronađena su <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item>
- <item quantity="other">Pronađeno je <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item>
+ <item quantity="one">Пронађен је <xliff:g id="COUNT_1">%1$s</xliff:g> штампач</item>
+ <item quantity="few">Пронађена су <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item>
+ <item quantity="other">Пронађено је <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item>
</plurals>
<string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="printer_info_desc" msgid="7181988788991581654">"Još informacija o ovom štampaču"</string>
- <string name="notification_channel_progress" msgid="872788690775721436">"Aktivni zadaci štampanja"</string>
- <string name="notification_channel_failure" msgid="9042250774797916414">"Neuspeli zadaci štampanja"</string>
- <string name="could_not_create_file" msgid="3425025039427448443">"Pravljenje datoteke nije uspelo"</string>
- <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke usluge štampanja su onemogućene"</string>
- <string name="print_searching_for_printers" msgid="6550424555079932867">"Traženje štampača"</string>
- <string name="print_no_print_services" msgid="8561247706423327966">"Nijedna usluga štampanja nije omogućena"</string>
- <string name="print_no_printers" msgid="4869403323900054866">"Nije pronađen nijedan štampač"</string>
- <string name="cannot_add_printer" msgid="7840348733668023106">"Nije moguće dodati štampače"</string>
- <string name="select_to_add_printers" msgid="3800709038689830974">"Izaberite da biste dodali štampač"</string>
- <string name="enable_print_service" msgid="3482815747043533842">"Izaberite da biste omogućili"</string>
- <string name="enabled_services_title" msgid="7036986099096582296">"Omogućene usluge"</string>
- <string name="recommended_services_title" msgid="3799434882937956924">"Preporučene usluge"</string>
- <string name="disabled_services_title" msgid="7313253167968363211">"Onemogućene usluge"</string>
- <string name="all_services_title" msgid="5578662754874906455">"Sve usluge"</string>
+ <string name="printer_info_desc" msgid="7181988788991581654">"Још информација о овом штампачу"</string>
+ <string name="notification_channel_progress" msgid="872788690775721436">"Активни задаци штампања"</string>
+ <string name="notification_channel_failure" msgid="9042250774797916414">"Неуспели задаци штампања"</string>
+ <string name="could_not_create_file" msgid="3425025039427448443">"Прављење датотеке није успело"</string>
+ <string name="print_services_disabled_toast" msgid="9089060734685174685">"Неке услуге штампања су онемогућене"</string>
+ <string name="print_searching_for_printers" msgid="6550424555079932867">"Тражење штампача"</string>
+ <string name="print_no_print_services" msgid="8561247706423327966">"Ниједна услуга штампања није омогућена"</string>
+ <string name="print_no_printers" msgid="4869403323900054866">"Није пронађен ниједан штампач"</string>
+ <string name="cannot_add_printer" msgid="7840348733668023106">"Није могуће додати штампаче"</string>
+ <string name="select_to_add_printers" msgid="3800709038689830974">"Изаберите да бисте додали штампач"</string>
+ <string name="enable_print_service" msgid="3482815747043533842">"Изаберите да бисте омогућили"</string>
+ <string name="enabled_services_title" msgid="7036986099096582296">"Омогућене услуге"</string>
+ <string name="recommended_services_title" msgid="3799434882937956924">"Препоручене услуге"</string>
+ <string name="disabled_services_title" msgid="7313253167968363211">"Онемогућене услуге"</string>
+ <string name="all_services_title" msgid="5578662754874906455">"Све услуге"</string>
<plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
- <item quantity="one">Instalirajte da biste otkrili <xliff:g id="COUNT_1">%1$s</xliff:g> štampač</item>
- <item quantity="few">Instalirajte da biste otkrili <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item>
- <item quantity="other">Instalirajte da biste otkrili <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item>
+ <item quantity="one">Инсталирајте да бисте открили <xliff:g id="COUNT_1">%1$s</xliff:g> штампач</item>
+ <item quantity="few">Инсталирајте да бисте открили <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item>
+ <item quantity="other">Инсталирајте да бисте открили <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item>
</plurals>
- <string name="printing_notification_title_template" msgid="295903957762447362">"Štampa se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
- <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazuje se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
- <string name="failed_notification_title_template" msgid="2256217208186530973">"Greška štampača <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
- <string name="blocked_notification_title_template" msgid="1175435827331588646">"Štampač je blokirao <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
- <string name="cancel" msgid="4373674107267141885">"Otkaži"</string>
- <string name="restart" msgid="2472034227037808749">"Restartuj"</string>
- <string name="no_connection_to_printer" msgid="2159246915977282728">"Nema veze sa štampačem"</string>
- <string name="reason_unknown" msgid="5507940196503246139">"nepoznato"</string>
- <string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite li da koristite <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
- <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument može da prođe kroz jedan ili više servera na putu do štampača."</string>
+ <string name="printing_notification_title_template" msgid="295903957762447362">"Штампа се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отказује се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка штампача <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="blocked_notification_title_template" msgid="1175435827331588646">"Штампач је блокирао <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="cancel" msgid="4373674107267141885">"Откажи"</string>
+ <string name="restart" msgid="2472034227037808749">"Рестартуј"</string>
+ <string name="no_connection_to_printer" msgid="2159246915977282728">"Нема везе са штампачем"</string>
+ <string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
+ <string name="print_service_security_warning_title" msgid="2160752291246775320">"Желите ли да користите <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+ <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Документ може да прође кроз један или више сервера на путу до штампача."</string>
<string-array name="color_mode_labels">
- <item msgid="7602948745415174937">"Crno-belo"</item>
- <item msgid="2762241247228983754">"Boja"</item>
+ <item msgid="7602948745415174937">"Црно-бело"</item>
+ <item msgid="2762241247228983754">"Боја"</item>
</string-array>
<string-array name="duplex_mode_labels">
- <item msgid="3882302912790928315">"Ništa"</item>
- <item msgid="7296563835355641719">"Duga ivica"</item>
- <item msgid="79513688117503758">"Kratka ivica"</item>
+ <item msgid="3882302912790928315">"Ништа"</item>
+ <item msgid="7296563835355641719">"Дуга ивица"</item>
+ <item msgid="79513688117503758">"Кратка ивица"</item>
</string-array>
<string-array name="orientation_labels">
- <item msgid="4061931020926489228">"Uspravno"</item>
- <item msgid="3199660090246166812">"Vodoravno"</item>
+ <item msgid="4061931020926489228">"Усправно"</item>
+ <item msgid="3199660090246166812">"Водоравно"</item>
</string-array>
- <string name="print_write_error_message" msgid="5787642615179572543">"Upisivanje u datoteku nije moguće"</string>
- <string name="print_error_default_message" msgid="8602678405502922346">"Žao nam je, ovo nije uspelo. Probajte ponovo."</string>
- <string name="print_error_retry" msgid="1426421728784259538">"Probajte ponovo"</string>
- <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ovaj štampač trenutno nije dostupan."</string>
- <string name="print_cannot_load_page" msgid="6179560924492912009">"Nije uspeo prikaz pregleda"</string>
- <string name="print_preparing_preview" msgid="3939930735671364712">"Priprema pregleda..."</string>
+ <string name="print_write_error_message" msgid="5787642615179572543">"Уписивање у датотеку није могуће"</string>
+ <string name="print_error_default_message" msgid="8602678405502922346">"Жао нам је, ово није успело. Пробајте поново."</string>
+ <string name="print_error_retry" msgid="1426421728784259538">"Пробајте поново"</string>
+ <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Овај штампач тренутно није доступан."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Није успео приказ прегледа"</string>
+ <string name="print_preparing_preview" msgid="3939930735671364712">"Припрема прегледа..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml
index 3ab43f1..c11e2b7 100644
--- a/packages/PrintSpooler/res/values-te/strings.xml
+++ b/packages/PrintSpooler/res/values-te/strings.xml
@@ -49,10 +49,10 @@
<string name="print_options_collapsed" msgid="7455930445670414332">"ముద్రణ ఎంపికలు కుదించబడ్డాయి"</string>
<string name="search" msgid="5421724265322228497">"సెర్చ్"</string>
<string name="all_printers_label" msgid="3178848870161526399">"అన్ని ప్రింటర్లు"</string>
- <string name="add_print_service_label" msgid="5356702546188981940">"సేవను జోడించు"</string>
+ <string name="add_print_service_label" msgid="5356702546188981940">"సేవను జోడించండి"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"సెర్చ్ బాక్స్ చూపబడింది"</string>
<string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"సెర్చ్ బాక్స్ దాచబడింది"</string>
- <string name="print_add_printer" msgid="1088656468360653455">"ప్రింటర్ను జోడించు"</string>
+ <string name="print_add_printer" msgid="1088656468360653455">"ప్రింటర్ను జోడించండి"</string>
<string name="print_select_printer" msgid="7388760939873368698">"ప్రింటర్ను ఎంచుకోండి"</string>
<string name="print_forget_printer" msgid="5035287497291910766">"ప్రింటర్ను విస్మరించు"</string>
<plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/BannerMessagePreference/res/values-b+sr+Latn/strings.xml
index ca16c3d..68a2d5b 100644
--- a/packages/SettingsLib/BannerMessagePreference/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/BannerMessagePreference/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"Odbacite"</string>
+ <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"Одбаците"</string>
</resources>
diff --git a/packages/SettingsLib/FooterPreference/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/FooterPreference/res/values-b+sr+Latn/strings.xml
index 993ec9a..9a73269 100644
--- a/packages/SettingsLib/FooterPreference/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/FooterPreference/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="settingslib_learn_more_text" msgid="7385478101223578464">"Saznajte više"</string>
+ <string name="settingslib_learn_more_text" msgid="7385478101223578464">"Сазнајте више"</string>
</resources>
diff --git a/packages/SettingsLib/HelpUtils/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/HelpUtils/res/values-b+sr+Latn/strings.xml
index a917a76..ee550bc 100644
--- a/packages/SettingsLib/HelpUtils/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="help_feedback_label" msgid="7106780063063027882">"Pomoć i povratne informacije"</string>
+ <string name="help_feedback_label" msgid="7106780063063027882">"Помоћ и повратне информације"</string>
</resources>
diff --git a/packages/SettingsLib/IllustrationPreference/res/values/colors.xml b/packages/SettingsLib/IllustrationPreference/res/values/colors.xml
index 0de7be0..5d6c343 100644
--- a/packages/SettingsLib/IllustrationPreference/res/values/colors.xml
+++ b/packages/SettingsLib/IllustrationPreference/res/values/colors.xml
@@ -40,6 +40,7 @@
<color name="settingslib_color_grey800">#3c4043</color>
<color name="settingslib_color_grey700">#5f6368</color>
<color name="settingslib_color_grey600">#80868b</color>
+ <color name="settingslib_color_grey500">#9AA0A6</color>
<color name="settingslib_color_grey400">#bdc1c6</color>
<color name="settingslib_color_grey300">#dadce0</color>
<color name="settingslib_color_grey200">#e8eaed</color>
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java
index 93b6acc..5e2c437 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java
@@ -40,10 +40,13 @@
HashMap<String, Integer> map = new HashMap<>();
map.put(
".grey600",
- R.color.settingslib_color_grey300);
+ R.color.settingslib_color_grey400);
+ map.put(
+ ".grey700",
+ R.color.settingslib_color_grey500);
map.put(
".grey800",
- R.color.settingslib_color_grey200);
+ R.color.settingslib_color_grey300);
map.put(
".grey900",
R.color.settingslib_color_grey50);
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml
index e09afbf..9d006a7 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-b+sr+Latn/strings.xml
@@ -17,6 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="enabled_by_admin" msgid="6630472777476410137">"Administrator je omogućio"</string>
- <string name="disabled_by_admin" msgid="4023569940620832713">"Administrator je onemogućio"</string>
+ <string name="enabled_by_admin" msgid="6630472777476410137">"Администратор је омогућио"</string>
+ <string name="disabled_by_admin" msgid="4023569940620832713">"Администратор је онемогућио"</string>
</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml
index 112b2ea..81a7baf 100644
--- a/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1914043873178389845">"Pretražite podešavanja"</string>
+ <string name="search_menu" msgid="1914043873178389845">"Претражите подешавања"</string>
</resources>
diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/SelectorWithWidgetPreference/res/values-b+sr+Latn/strings.xml
index d51823f..1478a00 100644
--- a/packages/SettingsLib/SelectorWithWidgetPreference/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/SelectorWithWidgetPreference/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="settings_label" msgid="5948970810295631236">"Podešavanja"</string>
+ <string name="settings_label" msgid="5948970810295631236">"Подешавања"</string>
</resources>
diff --git a/packages/SettingsLib/res/drawable/ic_bt_le_audio.xml b/packages/SettingsLib/res/drawable/ic_bt_le_audio.xml
index 5b52a04..6afeaf8 100644
--- a/packages/SettingsLib/res/drawable/ic_bt_le_audio.xml
+++ b/packages/SettingsLib/res/drawable/ic_bt_le_audio.xml
@@ -13,6 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
+<!-- The LE audio icon is like headphones and it is the same as ic_bt_headset_hfp.xml-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
@@ -20,12 +22,8 @@
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal" >
<path
- android:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z"
- android:fillColor="#FFFFFFFF"/>
- <path
- android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"
- android:fillColor="#FFFFFFFF"/>
- <path
- android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z"
- android:fillColor="#FFFFFFFF"/>
+ android:fillColor="#FF000000"
+ android:pathData="M12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87
+ 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h4v1h-7v2h6c1.66,0 3,-1.34 3,-3V10c0,-4.97 -4.03,-9
+ -9,-9z"/>
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_bt_le_audio_speakers.xml b/packages/SettingsLib/res/drawable/ic_bt_le_audio_speakers.xml
new file mode 100644
index 0000000..ac3053a
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_bt_le_audio_speakers.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorControlNormal" >
+ <path
+ android:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z"
+ android:fillColor="#FFFFFFFF"/>
+ <path
+ android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"
+ android:fillColor="#FFFFFFFF"/>
+ <path
+ android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z"
+ android:fillColor="#FFFFFFFF"/>
+</vector>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index dce7a85..d11cd9e 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> oor tot vol"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> oor tot vol"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Laaiproses is onderbreek"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laai tot <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Laai"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laai tans vinnig"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index adbdf22..ec3942e 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -477,9 +477,9 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"እስኪሞላ ድረስ <xliff:g id="TIME">%1$s</xliff:g> ይቀራል"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
- <!-- no translation found for power_charging_limited (6732738149313642521) -->
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
<skip />
- <!-- no translation found for power_charging_future_paused (6829683663982987290) -->
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
<skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"ያልታወቀ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ኃይል በመሙላት ላይ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 0ec610d..f451091 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"يتبقّى <xliff:g id="TIME">%1$s</xliff:g> حتى اكتمال شحن البطارية."</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقّى <xliff:g id="TIME">%2$s</xliff:g> حتى اكتمال شحن البطارية."</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - الشحن متوقّف مؤقتًا"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - الشحن حتى <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"غير معروف"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"جارٍ الشحن"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"جارٍ الشحن سريعًا"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 1598fd1..27ea8cb 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"সম্পূৰ্ণ হ’বলৈ <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"সম্পূৰ্ণ হ’বলৈ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - চাৰ্জিং পজ কৰা হৈছে"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>লৈ চাৰ্জিং"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"অজ্ঞাত"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"চাৰ্জ কৰি থকা হৈছে"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্ৰুততাৰে চাৰ্জ হৈছে"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index e03fd58..e167f6a 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Tam şarj edilənədək <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - tam şarj edilənədək <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj durdurulub"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> olana qədər şarj edilir"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Naməlum"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Enerji doldurma"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Sürətlə doldurulur"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index 63b08fa..a95e47b 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -22,49 +22,49 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array name="wifi_status">
<item msgid="1596683495752107015"></item>
- <item msgid="3288373008277313483">"Skeniranje..."</item>
- <item msgid="6050951078202663628">"Povezivanje…"</item>
- <item msgid="8356618438494652335">"Potvrđuje se autentičnost..."</item>
- <item msgid="2837871868181677206">"Preuzimanje IP adrese..."</item>
- <item msgid="4613015005934755724">"Povezano"</item>
- <item msgid="3763530049995655072">"Obustavljeno"</item>
- <item msgid="7852381437933824454">"Prekidanje veze..."</item>
- <item msgid="5046795712175415059">"Veza je prekinuta"</item>
- <item msgid="2473654476624070462">"Neuspešno"</item>
- <item msgid="9146847076036105115">"Blokirano"</item>
- <item msgid="4543924085816294893">"Privremeno izbegavanje loše veze"</item>
+ <item msgid="3288373008277313483">"Скенирање..."</item>
+ <item msgid="6050951078202663628">"Повезивање…"</item>
+ <item msgid="8356618438494652335">"Потврђује се аутентичност..."</item>
+ <item msgid="2837871868181677206">"Преузимање IP адресе..."</item>
+ <item msgid="4613015005934755724">"Повезано"</item>
+ <item msgid="3763530049995655072">"Обустављено"</item>
+ <item msgid="7852381437933824454">"Прекидање везе..."</item>
+ <item msgid="5046795712175415059">"Веза је прекинута"</item>
+ <item msgid="2473654476624070462">"Неуспешно"</item>
+ <item msgid="9146847076036105115">"Блокирано"</item>
+ <item msgid="4543924085816294893">"Привремено избегавање лоше везе"</item>
</string-array>
<string-array name="wifi_status_with_ssid">
<item msgid="5969842512724979061"></item>
- <item msgid="1818677602615822316">"Skeniranje..."</item>
- <item msgid="8339720953594087771">"Povezivanje sa mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="3028983857109369308">"Proveravanje identiteta mreže <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
- <item msgid="4287401332778341890">"Dobijanje IP adrese od mreže <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="1043944043827424501">"Povezano sa mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
- <item msgid="7445993821842009653">"Obustavljeno"</item>
- <item msgid="1175040558087735707">"Prekidanje veze sa mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="699832486578171722">"Veza je prekinuta"</item>
- <item msgid="522383512264986901">"Neuspešno"</item>
- <item msgid="3602596701217484364">"Blokirano"</item>
- <item msgid="1999413958589971747">"Privremeno izbegavanje loše veze"</item>
+ <item msgid="1818677602615822316">"Скенирање..."</item>
+ <item msgid="8339720953594087771">"Повезивање са мрежом <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="3028983857109369308">"Проверавање идентитета мреже <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
+ <item msgid="4287401332778341890">"Добијање IP адресе од мреже <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="1043944043827424501">"Повезано са мрежом <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
+ <item msgid="7445993821842009653">"Обустављено"</item>
+ <item msgid="1175040558087735707">"Прекидање везе са мрежом <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="699832486578171722">"Веза је прекинута"</item>
+ <item msgid="522383512264986901">"Неуспешно"</item>
+ <item msgid="3602596701217484364">"Блокирано"</item>
+ <item msgid="1999413958589971747">"Привремено избегавање лоше везе"</item>
</string-array>
<string-array name="hdcp_checking_titles">
- <item msgid="2377230797542526134">"Nikad ne proveravaj"</item>
- <item msgid="3919638466823112484">"Potraži samo DRM sadržaj"</item>
- <item msgid="9048424957228926377">"Uvek proveravaj"</item>
+ <item msgid="2377230797542526134">"Никад не проверавај"</item>
+ <item msgid="3919638466823112484">"Потражи само DRM садржај"</item>
+ <item msgid="9048424957228926377">"Увек проверавај"</item>
</string-array>
<string-array name="hdcp_checking_summaries">
- <item msgid="4045840870658484038">"Nikada ne koristi HDCP proveru"</item>
- <item msgid="8254225038262324761">"Koristi HDCP proveru samo za DRM sadržaj"</item>
- <item msgid="6421717003037072581">"Uvek koristi HDCP proveru"</item>
+ <item msgid="4045840870658484038">"Никада не користи HDCP проверу"</item>
+ <item msgid="8254225038262324761">"Користи HDCP проверу само за DRM садржај"</item>
+ <item msgid="6421717003037072581">"Увек користи HDCP проверу"</item>
</string-array>
<string-array name="bt_hci_snoop_log_entries">
- <item msgid="695678520785580527">"Onemogućeno"</item>
- <item msgid="6336372935919715515">"Omogućeno filtrirano"</item>
- <item msgid="2779123106632690576">"Omogućeno"</item>
+ <item msgid="695678520785580527">"Онемогућено"</item>
+ <item msgid="6336372935919715515">"Омогућено филтрирано"</item>
+ <item msgid="2779123106632690576">"Омогућено"</item>
</string-array>
<string-array name="bluetooth_avrcp_versions">
- <item msgid="6603880723315236832">"AVRCP 1.5 (podrazumevano)"</item>
+ <item msgid="6603880723315236832">"AVRCP 1.5 (подразумевано)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
<item msgid="5896162189744596291">"AVRCP 1.4"</item>
<item msgid="7556896992111771426">"AVRCP 1.6"</item>
@@ -76,7 +76,7 @@
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
<string-array name="bluetooth_map_versions">
- <item msgid="8786402640610987099">"MAP 1.2 (podrazumevano)"</item>
+ <item msgid="8786402640610987099">"MAP 1.2 (подразумевано)"</item>
<item msgid="6817922176194686449">"MAP 1.3"</item>
<item msgid="3423518690032737851">"MAP 1.4"</item>
</string-array>
@@ -86,81 +86,81 @@
<item msgid="8147982633566548515">"map14"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_titles">
- <item msgid="2494959071796102843">"Koristi izbor sistema (podrazumevano)"</item>
+ <item msgid="2494959071796102843">"Користи избор система (подразумевано)"</item>
<item msgid="4055460186095649420">"SBC"</item>
<item msgid="720249083677397051">"AAC"</item>
- <item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
- <item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
+ <item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
+ <item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="3825367753087348007">"LDAC"</item>
<item msgid="328951785723550863">"LC3"</item>
<item msgid="506175145534048710">"Opus"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
- <item msgid="8868109554557331312">"Koristi izbor sistema (podrazumevano)"</item>
+ <item msgid="8868109554557331312">"Користи избор система (подразумевано)"</item>
<item msgid="9024885861221697796">"SBC"</item>
<item msgid="4688890470703790013">"AAC"</item>
- <item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
- <item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
+ <item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
+ <item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="2553206901068987657">"LDAC"</item>
<item msgid="3940992993241040716">"LC3"</item>
<item msgid="7940970833006181407">"Opus"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
- <item msgid="926809261293414607">"Koristi izbor sistema (podrazumevano)"</item>
+ <item msgid="926809261293414607">"Користи избор система (подразумевано)"</item>
<item msgid="8003118270854840095">"44,1 kHz"</item>
<item msgid="3208896645474529394">"48,0 kHz"</item>
<item msgid="8420261949134022577">"88,2 kHz"</item>
<item msgid="8887519571067543785">"96,0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
- <item msgid="2284090879080331090">"Koristi izbor sistema (podrazumevano)"</item>
+ <item msgid="2284090879080331090">"Користи избор система (подразумевано)"</item>
<item msgid="1872276250541651186">"44,1 kHz"</item>
<item msgid="8736780630001704004">"48,0 kHz"</item>
<item msgid="7698585706868856888">"88,2 kHz"</item>
<item msgid="8946330945963372966">"96,0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
- <item msgid="2574107108483219051">"Koristi izbor sistema (podrazumevano)"</item>
- <item msgid="4671992321419011165">"16 bitova po uzorku"</item>
- <item msgid="1933898806184763940">"24 bita po uzorku"</item>
- <item msgid="1212577207279552119">"32 bita po uzorku"</item>
+ <item msgid="2574107108483219051">"Користи избор система (подразумевано)"</item>
+ <item msgid="4671992321419011165">"16 битова по узорку"</item>
+ <item msgid="1933898806184763940">"24 бита по узорку"</item>
+ <item msgid="1212577207279552119">"32 бита по узорку"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
- <item msgid="9196208128729063711">"Koristi izbor sistema (podrazumevano)"</item>
- <item msgid="1084497364516370912">"16 bitova po uzorku"</item>
- <item msgid="2077889391457961734">"24 bita po uzorku"</item>
- <item msgid="3836844909491316925">"32 bita po uzorku"</item>
+ <item msgid="9196208128729063711">"Користи избор система (подразумевано)"</item>
+ <item msgid="1084497364516370912">"16 битова по узорку"</item>
+ <item msgid="2077889391457961734">"24 бита по узорку"</item>
+ <item msgid="3836844909491316925">"32 бита по узорку"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_titles">
- <item msgid="3014194562841654656">"Koristi izbor sistema (podrazumevano)"</item>
- <item msgid="5982952342181788248">"Mono"</item>
- <item msgid="927546067692441494">"Stereo"</item>
+ <item msgid="3014194562841654656">"Користи избор система (подразумевано)"</item>
+ <item msgid="5982952342181788248">"Моно"</item>
+ <item msgid="927546067692441494">"Стерео"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
- <item msgid="1997302811102880485">"Koristi izbor sistema (podrazumevano)"</item>
- <item msgid="8005696114958453588">"Mono"</item>
- <item msgid="1333279807604675720">"Stereo"</item>
+ <item msgid="1997302811102880485">"Користи избор система (подразумевано)"</item>
+ <item msgid="8005696114958453588">"Моно"</item>
+ <item msgid="1333279807604675720">"Стерео"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="1241278021345116816">"Optimizovano za kvalitet zvuka (990 kb/s/909 kb/s)"</item>
- <item msgid="3523665555859696539">"Ujednačen kvalitet zvuka i veze (660 kb/s/606 kb/s)"</item>
- <item msgid="886408010459747589">"Optimizovano za kvalitet veze (330 kb/s/303 kb/s)"</item>
- <item msgid="3808414041654351577">"Najbolje moguće (prilagodljiva brzina prenosa)"</item>
+ <item msgid="1241278021345116816">"Оптимизовано за квалитет звука (990 kb/s/909 kb/s)"</item>
+ <item msgid="3523665555859696539">"Уједначен квалитет звука и везе (660 kb/s/606 kb/s)"</item>
+ <item msgid="886408010459747589">"Оптимизовано за квалитет везе (330 kb/s/303 kb/s)"</item>
+ <item msgid="3808414041654351577">"Најбоље могуће (прилагодљива брзина преноса)"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="804499336721569838">"Optimizovano za kvalitet zvuka"</item>
- <item msgid="7451422070435297462">"Ujednačen kvalitet zvuka i veze"</item>
- <item msgid="6173114545795428901">"Optimizovano za kvalitet veze"</item>
- <item msgid="4349908264188040530">"Najbolje moguće (prilagodljiva brzina prenosa)"</item>
+ <item msgid="804499336721569838">"Оптимизовано за квалитет звука"</item>
+ <item msgid="7451422070435297462">"Уједначен квалитет звука и везе"</item>
+ <item msgid="6173114545795428901">"Оптимизовано за квалитет везе"</item>
+ <item msgid="4349908264188040530">"Најбоље могуће (прилагодљива брзина преноса)"</item>
</string-array>
<string-array name="bluetooth_audio_active_device_summaries">
<item msgid="8019740759207729126"></item>
- <item msgid="204248102837117183">", aktivan"</item>
- <item msgid="253388653486517049">", aktivan (medijski)"</item>
- <item msgid="5001852592115448348">", aktivan (telefon)"</item>
+ <item msgid="204248102837117183">", активан"</item>
+ <item msgid="253388653486517049">", активан (медијски)"</item>
+ <item msgid="5001852592115448348">", активан (телефон)"</item>
</string-array>
<string-array name="select_logd_size_titles">
- <item msgid="1191094707770726722">"Isključeno"</item>
+ <item msgid="1191094707770726722">"Искључено"</item>
<item msgid="7839165897132179888">"64 kB"</item>
<item msgid="2715700596495505626">"256 kB"</item>
<item msgid="7099386891713159947">"1 MB"</item>
@@ -168,107 +168,107 @@
<item msgid="6078203297886482480">"8 MB"</item>
</string-array>
<string-array name="select_logd_size_lowram_titles">
- <item msgid="1145807928339101085">"Isključeno"</item>
+ <item msgid="1145807928339101085">"Искључено"</item>
<item msgid="4064786181089783077">"64 kB"</item>
<item msgid="3052710745383602630">"256 kB"</item>
<item msgid="3691785423374588514">"1 MB"</item>
</string-array>
<string-array name="select_logd_size_summaries">
- <item msgid="409235464399258501">"Isključeno"</item>
- <item msgid="4195153527464162486">"64 kB po međumemoriji evidencije"</item>
- <item msgid="7464037639415220106">"256 kB po međumemoriji evidencije"</item>
- <item msgid="8539423820514360724">"1 MB po međumemoriji evidencije"</item>
- <item msgid="1984761927103140651">"4 MB po međumemoriji evidencije"</item>
- <item msgid="2983219471251787208">"8 MB po međumemoriji evidencije"</item>
+ <item msgid="409235464399258501">"Искључено"</item>
+ <item msgid="4195153527464162486">"64 kB по међумеморији евиденције"</item>
+ <item msgid="7464037639415220106">"256 kB по међумеморији евиденције"</item>
+ <item msgid="8539423820514360724">"1 MB по међумеморији евиденције"</item>
+ <item msgid="1984761927103140651">"4 MB по међумеморији евиденције"</item>
+ <item msgid="2983219471251787208">"8 MB по међумеморији евиденције"</item>
</string-array>
<string-array name="select_logpersist_titles">
- <item msgid="704720725704372366">"Isključeno"</item>
- <item msgid="6014837961827347618">"Sve"</item>
- <item msgid="7387060437894578132">"Sve sem radija"</item>
- <item msgid="7300881231043255746">"samo jezgro"</item>
+ <item msgid="704720725704372366">"Искључено"</item>
+ <item msgid="6014837961827347618">"Све"</item>
+ <item msgid="7387060437894578132">"Све сeм радија"</item>
+ <item msgid="7300881231043255746">"само језгро"</item>
</string-array>
<string-array name="select_logpersist_summaries">
- <item msgid="97587758561106269">"Isključeno"</item>
- <item msgid="7126170197336963369">"Sve međumemorije evidencija"</item>
- <item msgid="7167543126036181392">"Sve osim međumemorija evidencija za radio"</item>
- <item msgid="5135340178556563979">"samo međumemorija evidencije jezgra"</item>
+ <item msgid="97587758561106269">"Искључено"</item>
+ <item msgid="7126170197336963369">"Све међумеморије евиденција"</item>
+ <item msgid="7167543126036181392">"Све осим међумеморија евиденција за радио"</item>
+ <item msgid="5135340178556563979">"само међумеморија евиденције језгра"</item>
</string-array>
<string-array name="window_animation_scale_entries">
- <item msgid="2675263395797191850">"Animacija je isključena"</item>
- <item msgid="5790132543372767872">"Razmera animacije 0,5x"</item>
- <item msgid="2529692189302148746">"Razmera animacije 1x"</item>
- <item msgid="8072785072237082286">"Razmera animacije 1,5x"</item>
- <item msgid="3531560925718232560">"Razmera animacije 2x"</item>
- <item msgid="4542853094898215187">"Razmera animacije 5x"</item>
- <item msgid="5643881346223901195">"Razmera animacije 10x"</item>
+ <item msgid="2675263395797191850">"Анимација је искључена"</item>
+ <item msgid="5790132543372767872">"Размера анимације 0,5x"</item>
+ <item msgid="2529692189302148746">"Размера анимације 1x"</item>
+ <item msgid="8072785072237082286">"Размера анимације 1,5x"</item>
+ <item msgid="3531560925718232560">"Размера анимације 2x"</item>
+ <item msgid="4542853094898215187">"Размера анимације 5x"</item>
+ <item msgid="5643881346223901195">"Размера анимације 10x"</item>
</string-array>
<string-array name="transition_animation_scale_entries">
- <item msgid="3376676813923486384">"Animacija je isključena"</item>
- <item msgid="753422683600269114">"Razmera animacije 0,5x"</item>
- <item msgid="3695427132155563489">"Razmera animacije 1x"</item>
- <item msgid="9032615844198098981">"Razmera animacije 1,5x"</item>
- <item msgid="8473868962499332073">"Razmera animacije 2x"</item>
- <item msgid="4403482320438668316">"Razmera animacije 5x"</item>
- <item msgid="169579387974966641">"Razmera animacije 10x"</item>
+ <item msgid="3376676813923486384">"Анимација је искључена"</item>
+ <item msgid="753422683600269114">"Размера анимације 0,5x"</item>
+ <item msgid="3695427132155563489">"Размера анимације 1x"</item>
+ <item msgid="9032615844198098981">"Размера анимације 1,5x"</item>
+ <item msgid="8473868962499332073">"Размера анимације 2x"</item>
+ <item msgid="4403482320438668316">"Размера анимације 5x"</item>
+ <item msgid="169579387974966641">"Размера анимације 10x"</item>
</string-array>
<string-array name="animator_duration_scale_entries">
- <item msgid="6416998593844817378">"Animacija je isključena"</item>
- <item msgid="875345630014338616">"Razmera animacije 0,5x"</item>
- <item msgid="2753729231187104962">"Razmera animacije 1x"</item>
- <item msgid="1368370459723665338">"Razmera animacije 1,5x"</item>
- <item msgid="5768005350534383389">"Razmera animacije 2x"</item>
- <item msgid="3728265127284005444">"Razmera animacije 5x"</item>
- <item msgid="2464080977843960236">"Razmera animacije 10x"</item>
+ <item msgid="6416998593844817378">"Анимација је искључена"</item>
+ <item msgid="875345630014338616">"Размера анимације 0,5x"</item>
+ <item msgid="2753729231187104962">"Размера анимације 1x"</item>
+ <item msgid="1368370459723665338">"Размера анимације 1,5x"</item>
+ <item msgid="5768005350534383389">"Размера анимације 2x"</item>
+ <item msgid="3728265127284005444">"Размера анимације 5x"</item>
+ <item msgid="2464080977843960236">"Размера анимације 10x"</item>
</string-array>
<string-array name="overlay_display_devices_entries">
- <item msgid="4497393944195787240">"Ništa"</item>
- <item msgid="8461943978957133391">"480 piksela"</item>
- <item msgid="6923083594932909205">"480 piksela (bezbedno)"</item>
- <item msgid="1226941831391497335">"720 piksela"</item>
- <item msgid="7051983425968643928">"720 piksela (bezbedno)"</item>
- <item msgid="7765795608738980305">"1080 piksela"</item>
- <item msgid="8084293856795803592">"1080 piksela (bezbedno)"</item>
+ <item msgid="4497393944195787240">"Ништа"</item>
+ <item msgid="8461943978957133391">"480 пиксела"</item>
+ <item msgid="6923083594932909205">"480 пиксела (безбедно)"</item>
+ <item msgid="1226941831391497335">"720 пиксела"</item>
+ <item msgid="7051983425968643928">"720 пиксела (безбедно)"</item>
+ <item msgid="7765795608738980305">"1080 пиксела"</item>
+ <item msgid="8084293856795803592">"1080 пиксела (безбедно)"</item>
<item msgid="938784192903353277">"4K"</item>
- <item msgid="8612549335720461635">"4K (bezbedno)"</item>
- <item msgid="7322156123728520872">"4K (uvećana rezolucija)"</item>
- <item msgid="7735692090314849188">"4K (uvećana rezolucija, bezbedno)"</item>
- <item msgid="7346816300608639624">"720 piksela, 1080 piks. (2 ekrana)"</item>
+ <item msgid="8612549335720461635">"4K (безбедно)"</item>
+ <item msgid="7322156123728520872">"4K (увећана резолуција)"</item>
+ <item msgid="7735692090314849188">"4K (увећана резолуција, безбедно)"</item>
+ <item msgid="7346816300608639624">"720 пиксела, 1080 пикс. (2 екрана)"</item>
</string-array>
<string-array name="enable_opengl_traces_entries">
- <item msgid="4433736508877934305">"Nijedan"</item>
+ <item msgid="4433736508877934305">"Ниједан"</item>
<item msgid="9140053004929079158">"Logcat"</item>
- <item msgid="3866871644917859262">"Systrace (grafika)"</item>
- <item msgid="7345673972166571060">"Grupno pozivanje funkcije glGetError"</item>
+ <item msgid="3866871644917859262">"Systrace (графика)"</item>
+ <item msgid="7345673972166571060">"Групно позивање функције glGetError"</item>
</string-array>
<string-array name="show_non_rect_clip_entries">
- <item msgid="2482978351289846212">"Isključeno"</item>
- <item msgid="3405519300199774027">"Nacrtaj oblast za isecanje koja nije pravougaonog oblika plavom bojom"</item>
- <item msgid="1212561935004167943">"Istakni zelenom testirane komande za crtanje"</item>
+ <item msgid="2482978351289846212">"Искључено"</item>
+ <item msgid="3405519300199774027">"Нацртај област за исецање која није правоугаоног облика плавом бојом"</item>
+ <item msgid="1212561935004167943">"Истакни зеленом тестиране команде за цртање"</item>
</string-array>
<string-array name="track_frame_time_entries">
- <item msgid="634406443901014984">"Isključeno"</item>
- <item msgid="1288760936356000927">"Na ekranu u vidu traka"</item>
- <item msgid="5023908510820531131">"U <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
+ <item msgid="634406443901014984">"Искључено"</item>
+ <item msgid="1288760936356000927">"На екрану у виду трака"</item>
+ <item msgid="5023908510820531131">"У <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
</string-array>
<string-array name="debug_hw_overdraw_entries">
- <item msgid="1968128556747588800">"Isključi"</item>
- <item msgid="3033215374382962216">"Prikaži oblasti preklapanja"</item>
- <item msgid="3474333938380896988">"Prikaži oblasti za deuteranomaliju"</item>
+ <item msgid="1968128556747588800">"Искључи"</item>
+ <item msgid="3033215374382962216">"Прикажи области преклапања"</item>
+ <item msgid="3474333938380896988">"Прикажи области за деутераномалију"</item>
</string-array>
<string-array name="app_process_limit_entries">
- <item msgid="794656271086646068">"Standardno ograničenje"</item>
- <item msgid="8628438298170567201">"Bez pozadinskih procesa"</item>
- <item msgid="915752993383950932">"Najviše jedan proces"</item>
- <item msgid="8554877790859095133">"Najviše dva procesa"</item>
- <item msgid="9060830517215174315">"Najviše tri procesa"</item>
- <item msgid="6506681373060736204">"Najviše četiri procesa"</item>
+ <item msgid="794656271086646068">"Стандардно ограничење"</item>
+ <item msgid="8628438298170567201">"Без позадинских процеса"</item>
+ <item msgid="915752993383950932">"Највише један процес"</item>
+ <item msgid="8554877790859095133">"Највише два процеса"</item>
+ <item msgid="9060830517215174315">"Највише три процеса"</item>
+ <item msgid="6506681373060736204">"Највише четири процеса"</item>
</string-array>
<string-array name="usb_configuration_titles">
- <item msgid="3358668781763928157">"Puni se"</item>
- <item msgid="7804797564616858506">"MTP (protokol za transfer medija)"</item>
- <item msgid="910925519184248772">"PTP (protokol za prenos slika)"</item>
- <item msgid="3825132913289380004">"RNDIS (USB eternet)"</item>
- <item msgid="8828567335701536560">"Izvor zvuka"</item>
+ <item msgid="3358668781763928157">"Пуни се"</item>
+ <item msgid="7804797564616858506">"MTP (протокол за трансфер медија)"</item>
+ <item msgid="910925519184248772">"PTP (протокол за пренос слика)"</item>
+ <item msgid="3825132913289380004">"RNDIS (USB етернет)"</item>
+ <item msgid="8828567335701536560">"Извор звука"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
<string-array name="avatar_image_descriptions">
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index ef6023e..68af019 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/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="wifi_fail_to_scan" msgid="2333336097603822490">"Nije moguće skenirati mreže"</string>
+ <string name="wifi_fail_to_scan" msgid="2333336097603822490">"Није могуће скенирати мреже"</string>
<string name="wifi_security_short_wep" msgid="7939809393561636237">"WEP"</string>
<string name="wifi_security_short_wpa" msgid="6998160832497442533">"WPA"</string>
<string name="wifi_security_short_wpa2" msgid="7697856994856831026">"WPA2"</string>
@@ -30,10 +30,10 @@
<string name="wifi_security_short_eap_wpa2_wpa3" msgid="6455656470422244501">"RSN-EAP"</string>
<string name="wifi_security_short_sae" msgid="78353562671556266">"WPA3"</string>
<string name="wifi_security_short_psk_sae" msgid="4965830739185952958">"WPA2/WPA3"</string>
- <string name="wifi_security_short_none_owe" msgid="8827409046261759703">"Ništa/OWE"</string>
+ <string name="wifi_security_short_none_owe" msgid="8827409046261759703">"Ништа/OWE"</string>
<string name="wifi_security_short_owe" msgid="5073524307942025369">"OWE"</string>
<string name="wifi_security_short_eap_suiteb" msgid="4174071135081556115">"Suite-B-192"</string>
- <string name="wifi_security_none" msgid="7392696451280611452">"Nema"</string>
+ <string name="wifi_security_none" msgid="7392696451280611452">"Нема"</string>
<string name="wifi_security_wep" msgid="1413627788581122366">"WEP"</string>
<string name="wifi_security_wpa" msgid="1072450904799930636">"WPA-Personal"</string>
<string name="wifi_security_wpa2" msgid="4038267581230425543">"WPA2-Personal"</string>
@@ -46,591 +46,593 @@
<string name="wifi_security_passpoint" msgid="2209078477216565387">"Passpoint"</string>
<string name="wifi_security_sae" msgid="3644520541721422843">"WPA3-Personal"</string>
<string name="wifi_security_psk_sae" msgid="8135104122179904684">"WPA2/WPA3-Personal"</string>
- <string name="wifi_security_none_owe" msgid="5241745828327404101">"Ništa/Enhanced Open"</string>
+ <string name="wifi_security_none_owe" msgid="5241745828327404101">"Ништа/Enhanced Open"</string>
<string name="wifi_security_owe" msgid="3343421403561657809">"Enhanced Open"</string>
- <string name="wifi_security_eap_suiteb" msgid="415842785991698142">"WPA3-Enterprise, 192-bitni"</string>
- <string name="wifi_remembered" msgid="3266709779723179188">"Sačuvano"</string>
- <string name="wifi_disconnected" msgid="7054450256284661757">"Veza je prekinuta"</string>
- <string name="wifi_disabled_generic" msgid="2651916945380294607">"Onemogućeno"</string>
- <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP konfiguracija je otkazala"</string>
- <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nije povezano zbog lošeg kvaliteta mreže"</string>
- <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi veza je otkazala"</string>
- <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problem sa potvrdom identiteta"</string>
- <string name="wifi_cant_connect" msgid="5718417542623056783">"Povezivanje nije uspelo"</string>
- <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Povezivanje sa „<xliff:g id="AP_NAME">%1$s</xliff:g>“ nije uspelo"</string>
- <string name="wifi_check_password_try_again" msgid="8817789642851605628">"Proverite lozinku i probajte ponovo"</string>
- <string name="wifi_not_in_range" msgid="1541760821805777772">"Nije u opsegu"</string>
- <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Automatsko povezivanje nije uspelo"</string>
- <string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
- <string name="saved_network" msgid="7143698034077223645">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Povezani ste na mrežu sa ograničenjem"</string>
- <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezano preko %1$s"</string>
- <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezano preko dobavljača ocene mreže"</string>
- <string name="connected_via_passpoint" msgid="7735442932429075684">"Veza je uspostavljena preko pristupne tačke %1$s"</string>
- <string name="connected_via_app" msgid="3532267661404276584">"Povezano preko: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="available_via_passpoint" msgid="1716000261192603682">"Dostupna je preko pristupne tačke %1$s"</string>
- <string name="tap_to_sign_up" msgid="5356397741063740395">"Dodirnite da biste se registrovali"</string>
- <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nema interneta"</string>
- <string name="private_dns_broken" msgid="1984159464346556931">"Pristup privatnom DNS serveru nije uspeo"</string>
- <string name="wifi_limited_connection" msgid="1184778285475204682">"Ograničena veza"</string>
- <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nema interneta"</string>
- <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Treba da se prijavite"</string>
- <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Pristupna tačka je privremeno zauzeta"</string>
- <string name="connected_via_carrier" msgid="1968057009076191514">"Povezano preko %1$s"</string>
- <string name="available_via_carrier" msgid="465598683092718294">"Dostupno preko %1$s"</string>
- <string name="osu_opening_provider" msgid="4318105381295178285">"Otvara se <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
- <string name="osu_connect_failed" msgid="9107873364807159193">"Povezivanje nije uspelo"</string>
- <string name="osu_completing_sign_up" msgid="8412636665040390901">"Registracija se dovršava…"</string>
- <string name="osu_sign_up_failed" msgid="5605453599586001793">"Dovršavanje registracije nije uspelo. Dodirnite da biste probali ponovo."</string>
- <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registracija je dovršena. Povezuje se…"</string>
- <string name="speed_label_very_slow" msgid="8526005255731597666">"Veoma spora"</string>
- <string name="speed_label_slow" msgid="6069917670665664161">"Spora"</string>
- <string name="speed_label_okay" msgid="1253594383880810424">"Potvrdi"</string>
- <string name="speed_label_medium" msgid="9078405312828606976">"Srednja"</string>
- <string name="speed_label_fast" msgid="2677719134596044051">"Brza"</string>
- <string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brza"</string>
- <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string>
+ <string name="wifi_security_eap_suiteb" msgid="415842785991698142">"WPA3-Enterprise, 192-битни"</string>
+ <string name="wifi_remembered" msgid="3266709779723179188">"Сачувано"</string>
+ <string name="wifi_disconnected" msgid="7054450256284661757">"Веза је прекинута"</string>
+ <string name="wifi_disabled_generic" msgid="2651916945380294607">"Онемогућено"</string>
+ <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP конфигурација је отказала"</string>
+ <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Није повезано због лошег квалитета мреже"</string>
+ <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi веза је отказала"</string>
+ <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Проблем са потврдом идентитета"</string>
+ <string name="wifi_cant_connect" msgid="5718417542623056783">"Повезивање није успело"</string>
+ <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Повезивање са „<xliff:g id="AP_NAME">%1$s</xliff:g>“ није успело"</string>
+ <string name="wifi_check_password_try_again" msgid="8817789642851605628">"Проверите лозинку и пробајте поново"</string>
+ <string name="wifi_not_in_range" msgid="1541760821805777772">"Није у опсегу"</string>
+ <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Аутоматско повезивање није успело"</string>
+ <string name="wifi_no_internet" msgid="1774198889176926299">"Нема приступа интернету"</string>
+ <string name="saved_network" msgid="7143698034077223645">"Сачувао/ла је <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Повезани сте на мрежу са ограничењем"</string>
+ <string name="connected_via_network_scorer" msgid="7665725527352893558">"Аутоматски повезано преко %1$s"</string>
+ <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Аутоматски повезано преко добављача оцене мреже"</string>
+ <string name="connected_via_passpoint" msgid="7735442932429075684">"Веза је успостављена преко приступне тачке %1$s"</string>
+ <string name="connected_via_app" msgid="3532267661404276584">"Повезано преко: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="available_via_passpoint" msgid="1716000261192603682">"Доступна је преко приступне тачке %1$s"</string>
+ <string name="tap_to_sign_up" msgid="5356397741063740395">"Додирните да бисте се регистровали"</string>
+ <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Нема интернета"</string>
+ <string name="private_dns_broken" msgid="1984159464346556931">"Приступ приватном DNS серверу није успео"</string>
+ <string name="wifi_limited_connection" msgid="1184778285475204682">"Ограничена веза"</string>
+ <string name="wifi_status_no_internet" msgid="3799933875988829048">"Нема интернета"</string>
+ <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Треба да се пријавите"</string>
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Приступна тачка је привремено заузета"</string>
+ <string name="connected_via_carrier" msgid="1968057009076191514">"Повезано преко %1$s"</string>
+ <string name="available_via_carrier" msgid="465598683092718294">"Доступно преко %1$s"</string>
+ <string name="osu_opening_provider" msgid="4318105381295178285">"Отвара се <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="9107873364807159193">"Повезивање није успело"</string>
+ <string name="osu_completing_sign_up" msgid="8412636665040390901">"Регистрација се довршава…"</string>
+ <string name="osu_sign_up_failed" msgid="5605453599586001793">"Довршавање регистрације није успело. Додирните да бисте пробали поново."</string>
+ <string name="osu_sign_up_complete" msgid="7640183358878916847">"Регистрација је довршена. Повезује се…"</string>
+ <string name="speed_label_very_slow" msgid="8526005255731597666">"Веома спора"</string>
+ <string name="speed_label_slow" msgid="6069917670665664161">"Спора"</string>
+ <string name="speed_label_okay" msgid="1253594383880810424">"Потврди"</string>
+ <string name="speed_label_medium" msgid="9078405312828606976">"Средња"</string>
+ <string name="speed_label_fast" msgid="2677719134596044051">"Брза"</string>
+ <string name="speed_label_very_fast" msgid="8215718029533182439">"Веома брза"</string>
+ <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Истекло"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="bluetooth_disconnected" msgid="7739366554710388701">"Veza je prekinuta"</string>
- <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekidanje veze..."</string>
- <string name="bluetooth_connecting" msgid="5871702668260192755">"Povezivanje…"</string>
- <string name="bluetooth_connected" msgid="8065345572198502293">"Povezano: <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"Uparivanje..."</string>
- <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Povezano (bez telefona): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Povezano (bez medija): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Povezano je (bez pristupa porukama): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Povezano (bez telefona ili medija): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Povezano, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Povezano (bez telefona), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Povezano (bez medija), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Povezano (bez telefona ili medija), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Aktivan, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Aktivno, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> baterije, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije"</string>
- <string name="bluetooth_battery_level" msgid="2893696778200201555">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> baterije, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije"</string>
- <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo s leve strane"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, s desne strane"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, s leve i desne strane"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk medija"</string>
- <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonski pozivi"</string>
- <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos datoteke"</string>
- <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup Internetu"</string>
- <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"Deljenje kontakata i istorije poziva"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"Koristite za deljenje kontakata i istorije poziva"</string>
- <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deljenje internet veze"</string>
- <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ovi"</string>
- <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Pristup SIM kartici"</string>
- <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD zvuk: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
- <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD zvuk"</string>
- <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni aparati"</string>
+ <string name="bluetooth_disconnected" msgid="7739366554710388701">"Веза је прекинута"</string>
+ <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Прекидање везе..."</string>
+ <string name="bluetooth_connecting" msgid="5871702668260192755">"Повезивање…"</string>
+ <string name="bluetooth_connected" msgid="8065345572198502293">"Повезано: <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"Упаривање..."</string>
+ <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Повезано (без телефона): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Повезано (без медија): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Повезано је (без приступа порукама): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Повезано (без телефона или медија): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Повезано, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Повезано (без телефона), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Повезано (без медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Повезано (без телефона или медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+ <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Активан, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Активно, Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерије, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерије"</string>
+ <string name="bluetooth_battery_level" msgid="2893696778200201555">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерије, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерије"</string>
+ <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активан"</string>
+ <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активно, само с леве стране"</string>
+ <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активно, с десне стране"</string>
+ <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активно, с леве и десне стране"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Звук медија"</string>
+ <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефонски позиви"</string>
+ <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос датотеке"</string>
+ <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Улазни уређај"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Приступ Интернету"</string>
+ <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"Дељење контаката и историје позива"</string>
+ <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"Користите за дељење контаката и историје позива"</string>
+ <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Дељење интернет везе"</string>
+ <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS-ови"</string>
+ <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Приступ SIM картици"</string>
+ <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD звук: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+ <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD звук"</string>
+ <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слушни апарати"</string>
<string name="bluetooth_profile_le_audio" msgid="3237854988278539061">"LE audio"</string>
- <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Povezano sa slušnim aparatima"</string>
- <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Povezano sa LE audio"</string>
- <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezano sa zvukom medija"</string>
- <string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Povezano sa zvukom telefona"</string>
- <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Povezano sa serverom za prenos datoteka"</string>
- <string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"Povezano je sa mapom"</string>
- <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"Veza sa tačkom pristupa uslugama je uspostavljena"</string>
- <string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"Nije povezano sa serverom za prenos datoteka"</string>
- <string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"Povezan sa ulaznim uređajem"</string>
- <string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"Povezano je sa uređajem radi pristupa internetu"</string>
- <string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"Lokalna internet veza se deli sa uređajem"</string>
- <string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Koristi za pristup internetu"</string>
- <string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Koristi se za mapu"</string>
- <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Koristi za pristup SIM kartici"</string>
- <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Korišćenje za zvuk medija"</string>
- <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Korišćenje za audio telefona"</string>
- <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Korišćenje za prenos datoteka"</string>
- <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Koristi za ulaz"</string>
- <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Koristi za slušne aparate"</string>
- <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Koristite za LE_AUDIO"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Upari"</string>
- <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"UPARI"</string>
- <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Otkaži"</string>
- <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Uparivanje omogućava pristup kontaktima i istoriji poziva nakon povezivanja."</string>
- <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Uparivanje sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Uparivanje sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće zbog netačnog PIN-a ili pristupnog koda."</string>
- <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nije moguće komunicirati sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> je odbio/la uparivanje"</string>
- <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Računar"</string>
- <string name="bluetooth_talkback_headset" msgid="3406852564400882682">"Naglavne slušalice"</string>
- <string name="bluetooth_talkback_phone" msgid="868393783858123880">"Pozovi"</string>
- <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"Obrada slika"</string>
- <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"Slušalice"</string>
- <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"Periferni uređaj za unos"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Повезано са слушним апаратима"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Повезано са LE audio"</string>
+ <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Повезано са звуком медија"</string>
+ <string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Повезано са звуком телефона"</string>
+ <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Повезано са сервером за пренос датотека"</string>
+ <string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"Повезано је са мапом"</string>
+ <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"Веза са тачком приступа услугама је успостављена"</string>
+ <string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"Није повезано са сервером за пренос датотека"</string>
+ <string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"Повезан са улазним уређајем"</string>
+ <string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"Повезано је са уређајем ради приступа интернету"</string>
+ <string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"Локална интернет веза се дели са уређајем"</string>
+ <string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Користи за приступ интернету"</string>
+ <string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Користи се за мапу"</string>
+ <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Користи за приступ SIM картици"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Коришћење за звук медија"</string>
+ <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Коришћење за аудио телефона"</string>
+ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Коришћење за пренос датотека"</string>
+ <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Користи за улаз"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Користи за слушне апарате"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Користите за LE_AUDIO"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Упари"</string>
+ <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"УПАРИ"</string>
+ <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Откажи"</string>
+ <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Упаривање омогућава приступ контактима и историји позива након повезивања."</string>
+ <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће због нетачног PIN-а или приступног кода."</string>
+ <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Није могуће комуницирати са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> је одбио/ла упаривање"</string>
+ <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Рачунар"</string>
+ <string name="bluetooth_talkback_headset" msgid="3406852564400882682">"Наглавне слушалице"</string>
+ <string name="bluetooth_talkback_phone" msgid="868393783858123880">"Позови"</string>
+ <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"Обрада слика"</string>
+ <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"Слушалице"</string>
+ <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"Периферни уређај за унос"</string>
<string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"Bluetooth"</string>
- <string name="accessibility_wifi_off" msgid="1195445715254137155">"WiFi je isključen."</string>
- <string name="accessibility_no_wifi" msgid="5297119459491085771">"WiFi veza je prekinuta."</string>
- <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"WiFi signal ima jednu crtu."</string>
- <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi signal ima dve crte."</string>
- <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi signal ima tri crte."</string>
- <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi signal je najjači."</string>
- <string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Otvorena mreža"</string>
- <string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Bezbedna mreža"</string>
- <string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
- <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Uklonjene aplikacije"</string>
- <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Uklonjene aplikacije i korisnici"</string>
- <string name="data_usage_ota" msgid="7984667793701597001">"Ažuriranja sistema"</string>
- <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB privezivanje"</string>
- <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Prenosni hotspot"</string>
- <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth privezivanje"</string>
- <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Privezivanje"</string>
- <string name="tether_settings_title_all" msgid="8910259483383010470">"Privezivanje i prenosni hotspot"</string>
- <string name="managed_user_title" msgid="449081789742645723">"Sve radne aplikacije"</string>
- <string name="unknown" msgid="3544487229740637809">"Nepoznato"</string>
- <string name="running_process_item_user_label" msgid="3988506293099805796">"Korisnik: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
- <string name="launch_defaults_some" msgid="3631650616557252926">"Podešene su neke podrazumevane vrednosti"</string>
- <string name="launch_defaults_none" msgid="8049374306261262709">"Nisu podešene podrazumevane vrednosti"</string>
- <string name="tts_settings" msgid="8130616705989351312">"Podešavanja prelaska iz teksta u govor"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"Pretvaranje teksta u govor"</string>
- <string name="tts_default_rate_title" msgid="3964187817364304022">"Brzina govora"</string>
- <string name="tts_default_rate_summary" msgid="3781937042151716987">"Brzina izgovaranja teksta"</string>
- <string name="tts_default_pitch_title" msgid="6988592215554485479">"Nivo"</string>
- <string name="tts_default_pitch_summary" msgid="9132719475281551884">"Utiče na ton sintetizovanog govora"</string>
- <string name="tts_default_lang_title" msgid="4698933575028098940">"Jezik"</string>
- <string name="tts_lang_use_system" msgid="6312945299804012406">"Koristi jezik sistema"</string>
- <string name="tts_lang_not_selected" msgid="7927823081096056147">"Jezik nije izabran"</string>
- <string name="tts_default_lang_summary" msgid="9042620014800063470">"Podešava glas specifičan za jezik namenjen govornom tekstu"</string>
- <string name="tts_play_example_title" msgid="1599468547216481684">"Poslušaj primer"</string>
- <string name="tts_play_example_summary" msgid="634044730710636383">"Puštanje kratke demonstracije sinteze govora"</string>
- <string name="tts_install_data_title" msgid="1829942496472751703">"Instaliraj glasovne podatke"</string>
- <string name="tts_install_data_summary" msgid="3608874324992243851">"Instaliranje govornih podataka potrebnih za sintezu govora"</string>
- <string name="tts_engine_security_warning" msgid="3372432853837988146">"Ova tehnologija za sintezu govora možda može da prikuplja sav tekst koji će biti izgovoren, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. To potiče iz tehnologije <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Želite li da omogućite korišćenje ove tehnologije za sintezu govora?"</string>
- <string name="tts_engine_network_required" msgid="8722087649733906851">"Za ovaj jezik je potrebna ispravna mrežna veza za pretvaranje teksta u govor."</string>
- <string name="tts_default_sample_string" msgid="6388016028292967973">"Ovo je primer sinteze govora"</string>
- <string name="tts_status_title" msgid="8190784181389278640">"Status podrazumevanog jezika"</string>
- <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> je podržan u potpunosti"</string>
- <string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g> zahteva vezu sa mrežom"</string>
- <string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g> nije podržan"</string>
- <string name="tts_status_checking" msgid="8026559918948285013">"Proverava se..."</string>
- <string name="tts_engine_settings_title" msgid="7849477533103566291">"Podešavanja za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
- <string name="tts_engine_settings_button" msgid="477155276199968948">"Pokreni podešavanja mašine"</string>
- <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Željena mašina"</string>
- <string name="tts_general_section_title" msgid="8919671529502364567">"Opšta"</string>
- <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Resetujte visinu tona govora"</string>
- <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Resetujte visinu tona kojom se tekst izgovara na podrazumevanu."</string>
+ <string name="accessibility_wifi_off" msgid="1195445715254137155">"WiFi је искључен."</string>
+ <string name="accessibility_no_wifi" msgid="5297119459491085771">"WiFi веза је прекинута."</string>
+ <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"WiFi сигнал има једну црту."</string>
+ <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi сигнал има две црте."</string>
+ <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi сигнал има три црте."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi сигнал је најјачи."</string>
+ <string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Отворена мрежа"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Безбедна мрежа"</string>
+ <string name="process_kernel_label" msgid="950292573930336765">"Android ОС"</string>
+ <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Уклоњене апликације"</string>
+ <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Уклоњене апликације и корисници"</string>
+ <string name="data_usage_ota" msgid="7984667793701597001">"Ажурирања система"</string>
+ <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB привезивање"</string>
+ <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Преносни хотспот"</string>
+ <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth привезивање"</string>
+ <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Привезивање"</string>
+ <string name="tether_settings_title_all" msgid="8910259483383010470">"Привезивање и преносни хотспот"</string>
+ <string name="managed_user_title" msgid="449081789742645723">"Све радне апликације"</string>
+ <string name="unknown" msgid="3544487229740637809">"Непознато"</string>
+ <string name="running_process_item_user_label" msgid="3988506293099805796">"Корисник: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+ <string name="launch_defaults_some" msgid="3631650616557252926">"Подешене су неке подразумеване вредности"</string>
+ <string name="launch_defaults_none" msgid="8049374306261262709">"Нису подешене подразумеване вредности"</string>
+ <string name="tts_settings" msgid="8130616705989351312">"Подешавања преласка из текста у говор"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"Претварање текста у говор"</string>
+ <string name="tts_default_rate_title" msgid="3964187817364304022">"Брзина говора"</string>
+ <string name="tts_default_rate_summary" msgid="3781937042151716987">"Брзина изговарања текста"</string>
+ <string name="tts_default_pitch_title" msgid="6988592215554485479">"Ниво"</string>
+ <string name="tts_default_pitch_summary" msgid="9132719475281551884">"Утиче на тон синтетизованог говора"</string>
+ <string name="tts_default_lang_title" msgid="4698933575028098940">"Језик"</string>
+ <string name="tts_lang_use_system" msgid="6312945299804012406">"Користи језик система"</string>
+ <string name="tts_lang_not_selected" msgid="7927823081096056147">"Језик није изабран"</string>
+ <string name="tts_default_lang_summary" msgid="9042620014800063470">"Подешава глас специфичан за језик намењен говорном тексту"</string>
+ <string name="tts_play_example_title" msgid="1599468547216481684">"Послушај пример"</string>
+ <string name="tts_play_example_summary" msgid="634044730710636383">"Пуштање кратке демонстрације синтезе говора"</string>
+ <string name="tts_install_data_title" msgid="1829942496472751703">"Инсталирај гласовне податке"</string>
+ <string name="tts_install_data_summary" msgid="3608874324992243851">"Инсталирање говорних података потребних за синтезу говора"</string>
+ <string name="tts_engine_security_warning" msgid="3372432853837988146">"Ова технологија за синтезу говора можда може да прикупља сав текст који ће бити изговорен, укључујући личне податке као што су лозинке и бројеви кредитних картица. То потиче из технологије <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Желите ли да омогућите коришћење ове технологије за синтезу говора?"</string>
+ <string name="tts_engine_network_required" msgid="8722087649733906851">"За овај језик је потребна исправна мрежна веза за претварање текста у говор."</string>
+ <string name="tts_default_sample_string" msgid="6388016028292967973">"Ово је пример синтезе говора"</string>
+ <string name="tts_status_title" msgid="8190784181389278640">"Статус подразумеваног језика"</string>
+ <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> је подржан у потпуности"</string>
+ <string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g> захтева везу са мрежом"</string>
+ <string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g> није подржан"</string>
+ <string name="tts_status_checking" msgid="8026559918948285013">"Проверава се..."</string>
+ <string name="tts_engine_settings_title" msgid="7849477533103566291">"Подешавања за <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
+ <string name="tts_engine_settings_button" msgid="477155276199968948">"Покрени подешавања машине"</string>
+ <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Жељена машина"</string>
+ <string name="tts_general_section_title" msgid="8919671529502364567">"Општа"</string>
+ <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Ресетујте висину тона говора"</string>
+ <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Ресетујте висину тона којом се текст изговара на подразумевану."</string>
<string-array name="tts_rate_entries">
- <item msgid="9004239613505400644">"Veoma sporo"</item>
- <item msgid="1815382991399815061">"Sporo"</item>
- <item msgid="3075292553049300105">"Normalno"</item>
- <item msgid="1158955023692670059">"Brzo"</item>
- <item msgid="5664310435707146591">"Brže"</item>
- <item msgid="5491266922147715962">"Veoma brzo"</item>
- <item msgid="7659240015901486196">"Ubrzano"</item>
- <item msgid="7147051179282410945">"Veoma ubrzano"</item>
- <item msgid="581904787661470707">"Najbrže"</item>
+ <item msgid="9004239613505400644">"Веома споро"</item>
+ <item msgid="1815382991399815061">"Споро"</item>
+ <item msgid="3075292553049300105">"Нормално"</item>
+ <item msgid="1158955023692670059">"Брзо"</item>
+ <item msgid="5664310435707146591">"Брже"</item>
+ <item msgid="5491266922147715962">"Веома брзо"</item>
+ <item msgid="7659240015901486196">"Убрзано"</item>
+ <item msgid="7147051179282410945">"Веома убрзано"</item>
+ <item msgid="581904787661470707">"Најбрже"</item>
</string-array>
- <string name="choose_profile" msgid="343803890897657450">"Izaberite profil"</string>
- <string name="category_personal" msgid="6236798763159385225">"Lično"</string>
- <string name="category_work" msgid="4014193632325996115">"Posao"</string>
- <string name="development_settings_title" msgid="140296922921597393">"Opcije za programere"</string>
- <string name="development_settings_enable" msgid="4285094651288242183">"Omogući opcije za programere"</string>
- <string name="development_settings_summary" msgid="8718917813868735095">"Podešavanje opcija za programiranje aplikacije"</string>
- <string name="development_settings_not_available" msgid="355070198089140951">"Opcije za programere nisu dostupne za ovog korisnika"</string>
- <string name="vpn_settings_not_available" msgid="2894137119965668920">"Podešavanja VPN-a nisu dostupna za ovog korisnika"</string>
- <string name="tethering_settings_not_available" msgid="266821736434699780">"Podešavanja privezivanja nisu dostupna za ovog korisnika"</string>
- <string name="apn_settings_not_available" msgid="1147111671403342300">"Podešavanja naziva pristupne tačke nisu dostupna za ovog korisnika"</string>
- <string name="enable_adb" msgid="8072776357237289039">"Otklanjanje USB grešaka"</string>
- <string name="enable_adb_summary" msgid="3711526030096574316">"Režim otklanjanja grešaka kada je USB povezan"</string>
- <string name="clear_adb_keys" msgid="3010148733140369917">"Opozivanje odobrenja za uklanjanje USB grešaka"</string>
- <string name="enable_adb_wireless" msgid="6973226350963971018">"Bežično otklanjanje grešaka"</string>
- <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Režim za otklanjanje grešaka kada je Wi‑Fi povezan"</string>
- <string name="adb_wireless_error" msgid="721958772149779856">"Greška"</string>
- <string name="adb_wireless_settings" msgid="2295017847215680229">"Bežično otklanjanje grešaka"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Da biste videli i koristili dostupne uređaje, uključite bežično otklanjanje grešaka"</string>
- <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Uparite uređaj pomoću QR koda"</string>
- <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Uparite nove uređaje pomoću čitača QR koda"</string>
- <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Uparite uređaj pomoću koda za uparivanje"</string>
- <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Uparite nove uređaje pomoću šestocifrenog koda"</string>
- <string name="adb_paired_devices_title" msgid="5268997341526217362">"Upareni uređaji"</string>
- <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Trenutno je povezano"</string>
- <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Detalji o uređaju"</string>
- <string name="adb_device_forget" msgid="193072400783068417">"Zaboravi"</string>
- <string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Otisak prsta na uređaju: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
- <string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Povezivanje nije uspelo"</string>
- <string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Uverite se da je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> povezan sa odgovarajućom mrežom"</string>
- <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Uparite sa uređajem"</string>
- <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Kôd za uparivanje preko Wi‑Fi-ja"</string>
- <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Uparivanje nije uspelo"</string>
- <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Uverite se da je uređaj povezan na istu mrežu."</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Uparite uređaj pomoću Wi‑Fi mreže ili tako što ćete skenirati QR kôd"</string>
- <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Uparuje se uređaj…"</string>
- <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Uparivanje uređaja nije uspelo. QR kôd je pogrešan ili uređaj nije povezan sa istom mrežom."</string>
- <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresa i port"</string>
- <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skeniraj QR kôd"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Uparite uređaj pomoću Wi‑Fi mreže tako što ćete skenirati QR kôd"</string>
- <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se na WiFi mrežu"</string>
- <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, otklanjanje grešaka, programer"</string>
- <string name="bugreport_in_power" msgid="8664089072534638709">"Prečica za izveštaj o greškama"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Prikazuje dugme u meniju dugmeta za uključivanje za pravljenje izveštaja o greškama"</string>
- <string name="keep_screen_on" msgid="1187161672348797558">"Ne zaključavaj"</string>
- <string name="keep_screen_on_summary" msgid="1510731514101925829">"Ekran neće biti u režimu spavanja tokom punjenja"</string>
- <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Omogući snoop evid. za Bluetooth HCI"</string>
- <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Snimi Bluetooth pakete. (Uključite/isključite Bluetooth kada promenite ovo podešavanje)"</string>
- <string name="oem_unlock_enable" msgid="5334869171871566731">"Otključavanje OEM-a"</string>
- <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Dozvoli otključavanje funkcije za pokretanje"</string>
- <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Želite li da dozvolite otključavanje proizvođača originalne opreme (OEM)?"</string>
- <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"UPOZORENJE: Funkcije za zaštitu uređaja neće funkcionisati na ovom uređaju dok je ovo podešavanje uključeno."</string>
- <string name="mock_location_app" msgid="6269380172542248304">"Izaberite aplikaciju za lažnu lokaciju"</string>
- <string name="mock_location_app_not_set" msgid="6972032787262831155">"Aplikacija za lažnu lokaciju nije podešena"</string>
- <string name="mock_location_app_set" msgid="4706722469342913843">"Aplikacija za lažnu lokaciju: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="debug_networking_category" msgid="6829757985772659599">"Umrežavanje"</string>
- <string name="wifi_display_certification" msgid="1805579519992520381">"Sertifikacija bežičnog ekrana"</string>
- <string name="wifi_verbose_logging" msgid="1785910450009679371">"Omogući detaljniju evidenciju za Wi‑Fi"</string>
- <string name="wifi_scan_throttling" msgid="2985624788509913617">"Usporavanje WiFi skeniranja"</string>
- <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Nasumično razvrstavanje MAC adresa po WiFi-ju sa prekidima"</string>
- <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilni podaci su uvek aktivni"</string>
- <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardversko ubrzanje privezivanja"</string>
- <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Prikaži Bluetooth uređaje bez naziva"</string>
- <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Onemogući glavno podešavanje jačine zvuka"</string>
- <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Omogući Gabeldorsche"</string>
- <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Verzija Bluetooth AVRCP-a"</string>
- <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Izaberite verziju Bluetooth AVRCP-a"</string>
- <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Verzija Bluetooth MAP-a"</string>
- <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Izaberite verziju Bluetooth MAP-a"</string>
- <string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth audio kodek"</string>
- <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Izaberite Bluetooth audio kodek\n"</string>
- <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Brzina uzorkovanja za Bluetooth audio"</string>
- <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"Izaberite Bluetooth audio kodek:\n brzina uzorkovanja"</string>
- <string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"Ako je neka stavka zasivljena, to znači da je telefon ili slušalice ne podržavaju"</string>
- <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"Bitova po uzorku za Bluetooth audio"</string>
- <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"Izaberite Bluetooth audio kodek:\n broj bitova po uzorku"</string>
- <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"Režim kanala za Bluetooth audio"</string>
- <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"Izaberite Bluetooth audio kodek:\n režim kanala"</string>
- <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"Bluetooth audio kodek LDAC: kvalitet reprodukcije"</string>
- <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Izaberite Bluetooth audio LDAC kodek:\n kvalitet snimka"</string>
- <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Strimovanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
- <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Privatni DNS"</string>
- <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Izaberite režim privatnog DNS-a"</string>
- <string name="private_dns_mode_off" msgid="7065962499349997041">"Isključeno"</string>
- <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automatski"</string>
- <string name="private_dns_mode_provider" msgid="3619040641762557028">"Ime hosta dobavljača usluge privatnog DNS-a"</string>
- <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Unesite ime hosta dobavljača usluge DNS-a"</string>
- <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Povezivanje nije uspelo"</string>
- <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Prikazuje opcije za sertifikaciju bežičnog ekrana"</string>
- <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string>
- <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Smanjuje potrošnju baterije i poboljšava učinak mreže"</string>
- <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Kada je ovaj režim omogućen, MAC adresa ovog uređaja može da se promeni svaki put kada se poveže sa mrežom na kojoj je omogućeno nasumično razvrstavanje MAC adresa."</string>
- <string name="wifi_metered_label" msgid="8737187690304098638">"Sa ograničenjem"</string>
- <string name="wifi_unmetered_label" msgid="6174142840934095093">"Bez ograničenja"</string>
- <string name="select_logd_size_title" msgid="1604578195914595173">"Veličine bafera podataka u programu za evidentiranje"</string>
- <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Izaberite veličine po baferu evidencije"</string>
- <string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Želite li da obrišete stalni memorijski prostor programa za evidentiranje?"</string>
- <string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Kada ih više ne nadgledamo pomoću stalnog programa za evidentiranje, dužni smo da obrišemo podatke iz programa za evidentiranje koji su trajno smešteni na uređaju."</string>
- <string name="select_logpersist_title" msgid="447071974007104196">"Čuvaj evidentirane podatke na uređaju"</string>
- <string name="select_logpersist_dialog_title" msgid="7745193591195485594">"Izaberite međumemorije evidencije koje ćete stalno čuvati na uređaju."</string>
- <string name="select_usb_configuration_title" msgid="6339801314922294586">"Izaberite konfiguraciju USB-a"</string>
- <string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Izaberite konfiguraciju USB-a"</string>
- <string name="allow_mock_location" msgid="2102650981552527884">"Dozvoli lažne lokacije"</string>
- <string name="allow_mock_location_summary" msgid="179780881081354579">"Dozvoli lažne lokacije"</string>
- <string name="debug_view_attributes" msgid="3539609843984208216">"Omogući proveru atributa za pregled"</string>
- <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Mobilni podaci su uvek aktivni, čak i kada je Wi‑Fi aktivan (radi brze promene mreže)."</string>
- <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Koristi se hardversko ubrzanje privezivanja ako je dostupno"</string>
- <string name="adb_warning_title" msgid="7708653449506485728">"Dozvoli otklanjanje USB grešaka?"</string>
- <string name="adb_warning_message" msgid="8145270656419669221">"Otklanjanje USB grešaka namenjeno je samo za svrhe programiranja. Koristite ga za kopiranje podataka sa računara na uređaj i obratno, instaliranje aplikacija na uređaju bez obaveštenja i čitanje podataka iz evidencije."</string>
- <string name="adbwifi_warning_title" msgid="727104571653031865">"Želite da dozvolite bežično otklanjanje grešaka?"</string>
- <string name="adbwifi_warning_message" msgid="8005936574322702388">"Bežično otklanjanje grešaka namenjeno je samo programiranju. Koristite ga za kopiranje podataka sa računara na uređaj i obratno, instaliranje aplikacija na uređaju bez obaveštenja i čitanje podataka iz evidencije."</string>
- <string name="adb_keys_warning_message" msgid="2968555274488101220">"Želite li da opozovete pristup otklanjanju USB grešaka sa svih računara koje ste prethodno odobrili?"</string>
- <string name="dev_settings_warning_title" msgid="8251234890169074553">"Želite li da omogućite programerska podešavanja?"</string>
- <string name="dev_settings_warning_message" msgid="37741686486073668">"Ova podešavanja su namenjena samo za programiranje. Mogu da izazovu prestanak funkcionisanja ili neočekivano ponašanje uređaja i aplikacija na njemu."</string>
- <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verifikuj aplikacije preko USB-a"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Proverava da li su aplikacije instalirane preko ADB-a/ADT-a štetne."</string>
- <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Prikazuje Bluetooth uređaje bez naziva (samo MAC adrese)"</string>
- <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Onemogućava glavno podešavanje jačine zvuka na Bluetooth uređaju u slučaju problema sa jačinom zvuka na daljinskim uređajima, kao što su izuzetno velika jačina zvuka ili nedostatak kontrole."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Omogućava grupu Bluetooth Gabeldorsche funkcija."</string>
- <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Omogućava funkciju Poboljšano povezivanje."</string>
- <string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
- <string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući apl. terminala za pristup lokalnom komandnom okruženju"</string>
- <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provera"</string>
- <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Podešavanje ponašanja HDCP provere"</string>
- <string name="debug_debugging_category" msgid="535341063709248842">"Otklanjanje grešaka"</string>
- <string name="debug_app" msgid="8903350241392391766">"Izaberite aplikaciju za otklanjanje grešaka"</string>
- <string name="debug_app_not_set" msgid="1934083001283807188">"Nema podešenih aplikacija za otklanjanje grešaka"</string>
- <string name="debug_app_set" msgid="6599535090477753651">"Aplikacija za otklanjanje grešaka: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="select_application" msgid="2543228890535466325">"Biranje aplikacije"</string>
- <string name="no_application" msgid="9038334538870247690">"Nijedna"</string>
- <string name="wait_for_debugger" msgid="7461199843335409809">"Sačekaj program za otklanjanje grešaka"</string>
- <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Aplikacija čeka program za otklanjanje grešaka da priloži pre izvršavanja"</string>
- <string name="debug_input_category" msgid="7349460906970849771">"Unos"</string>
- <string name="debug_drawing_category" msgid="5066171112313666619">"Crtanje"</string>
- <string name="debug_hw_drawing_category" msgid="5830815169336975162">"Hardverski ubrzano prikazivanje"</string>
- <string name="media_category" msgid="8122076702526144053">"Mediji"</string>
- <string name="debug_monitoring_category" msgid="1597387133765424994">"Nadgledanje"</string>
- <string name="strict_mode" msgid="889864762140862437">"Omogućen je strogi režim"</string>
- <string name="strict_mode_summary" msgid="1838248687233554654">"Ekran treperi kada aplikacije obavljaju duge operacije na glavnoj niti"</string>
- <string name="pointer_location" msgid="7516929526199520173">"Lokacija pokazivača"</string>
- <string name="pointer_location_summary" msgid="957120116989798464">"Preklopni element sa trenutnim podacima o dodiru"</string>
- <string name="show_touches" msgid="8437666942161289025">"Prikazuj dodire"</string>
- <string name="show_touches_summary" msgid="3692861665994502193">"Prikazuje vizuelne povratne informacije za dodire"</string>
- <string name="show_screen_updates" msgid="2078782895825535494">"Prikaži ažuriranja površine"</string>
- <string name="show_screen_updates_summary" msgid="2126932969682087406">"Osvetljava sve površine prozora kada se ažuriraju"</string>
- <string name="show_hw_screen_updates" msgid="2021286231267747506">"Prikaži ažuriranja prikaza"</string>
- <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Osvetljava prikaze u prozorima kada se crta"</string>
- <string name="show_hw_layers_updates" msgid="5268370750002509767">"Prikaži ažuriranja hardverskih slojeva"</string>
- <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Hardverski slojevi trepere zeleno kada se ažuriraju"</string>
- <string name="debug_hw_overdraw" msgid="8944851091008756796">"Otkloni greške GPU preklapanja"</string>
- <string name="disable_overlays" msgid="4206590799671557143">"Onemogući HW postavljene elemente"</string>
- <string name="disable_overlays_summary" msgid="1954852414363338166">"Uvek se koristi GPU za komponovanje ekrana"</string>
- <string name="simulate_color_space" msgid="1206503300335835151">"Simuliraj prostor boje"</string>
- <string name="enable_opengl_traces_title" msgid="4638773318659125196">"Omogući OpenGL tragove"</string>
- <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Onemogući USB preusm. zvuka"</string>
- <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Onemogućava automatsko preusmeravanje na USB audio periferne uređaje"</string>
- <string name="debug_layout" msgid="1659216803043339741">"Prikaži granice rasporeda"</string>
- <string name="debug_layout_summary" msgid="8825829038287321978">"Prikazuje granice klipa, margine itd."</string>
- <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Nametni smer rasporeda zdesna nalevo"</string>
- <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Nameće smer rasporeda ekrana zdesna nalevo za sve lokalitete"</string>
- <string name="window_blurs" msgid="6831008984828425106">"Dozvoli zamagljenja prozora"</string>
- <string name="force_msaa" msgid="4081288296137775550">"Nametni 4x MSAA"</string>
- <string name="force_msaa_summary" msgid="9070437493586769500">"Omogućava 4x MSAA u OpenGL ES 2.0 aplikacijama"</string>
- <string name="show_non_rect_clip" msgid="7499758654867881817">"Otkloni greške isecanja oblasti nepravougaonog oblika"</string>
- <string name="track_frame_time" msgid="522674651937771106">"Renderuj pomoću HWUI-a"</string>
- <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Omogući slojeve za otklanjanje grešaka GPU-a"</string>
- <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Učitava otklanjanje grešaka GPU-a u apl. za otklanjanje grešaka"</string>
- <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Opširne evidencije prodavca"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uvrštava u izveštaje o greškama dodatne posebne evidencije prodavca za uređaje, koje mogu da sadrže privatne podatke, da troše više baterije i/ili da koriste više memorije."</string>
- <string name="window_animation_scale_title" msgid="5236381298376812508">"Razmera animacije prozora"</string>
- <string name="transition_animation_scale_title" msgid="1278477690695439337">"Razmera animacije prelaza"</string>
- <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorova razmera trajanja"</string>
- <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuliraj sekundarne ekrane"</string>
- <string name="debug_applications_category" msgid="5394089406638954196">"Aplikacije"</string>
- <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ne čuvaj aktivnosti"</string>
- <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Uništava svaku aktivnost čim je korisnik napusti"</string>
- <string name="app_process_limit_title" msgid="8361367869453043007">"Ograničenje pozadinskih procesa"</string>
- <string name="show_all_anrs" msgid="9160563836616468726">"Prikaži ANR-ove u pozadini"</string>
- <string name="show_all_anrs_summary" msgid="8562788834431971392">"Prikazuje dijalog Aplikacija ne reaguje za aplikacije u pozadini"</string>
- <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Prikazuj upozorenja zbog kanala za obaveštenja"</string>
- <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Prikazuje upozorenje na ekranu kada aplikacija postavi obaveštenje bez važećeg kanala"</string>
- <string name="force_allow_on_external" msgid="9187902444231637880">"Prinudno dozvoli aplikacije u spoljnoj"</string>
- <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Omogućava upisivanje svih aplikacija u spoljnu memoriju, bez obzira na vrednosti manifesta"</string>
- <string name="force_resizable_activities" msgid="7143612144399959606">"Prinudno omogući promenu veličine aktivnosti"</string>
- <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogućava promenu veličine svih aktivnosti za režim sa više prozora, bez obzira na vrednosti manifesta."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore proizvoljnog formata"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućava podršku za eksperimentalne prozore proizvoljnog formata."</string>
- <string name="desktop_mode" msgid="2389067840550544462">"Režim za računare"</string>
- <string name="local_backup_password_title" msgid="4631017948933578709">"Lozinka rezervne kopije za računar"</string>
- <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervne kopije čitavog sistema trenutno nisu zaštićene"</string>
- <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da biste promenili ili uklonili lozinku za pravljenje rezervnih kopija čitavog sistema na računaru"</string>
- <string name="local_backup_password_toast_success" msgid="4891666204428091604">"Postavljena je nova lozinka rezervne kopije"</string>
- <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"Nova lozinka i njena potvrda se ne podudaraju"</string>
- <string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"Postavljanje lozinke rezervne kopije nije uspelo"</string>
- <string name="loading_injected_setting_summary" msgid="8394446285689070348">"Učitava se…"</string>
+ <string name="choose_profile" msgid="343803890897657450">"Изаберите профил"</string>
+ <string name="category_personal" msgid="6236798763159385225">"Лично"</string>
+ <string name="category_work" msgid="4014193632325996115">"Посао"</string>
+ <string name="development_settings_title" msgid="140296922921597393">"Опције за програмере"</string>
+ <string name="development_settings_enable" msgid="4285094651288242183">"Омогући опције за програмере"</string>
+ <string name="development_settings_summary" msgid="8718917813868735095">"Подешавање опција за програмирање апликације"</string>
+ <string name="development_settings_not_available" msgid="355070198089140951">"Опције за програмере нису доступне за овог корисника"</string>
+ <string name="vpn_settings_not_available" msgid="2894137119965668920">"Подешавања VPN-а нису доступна за овог корисника"</string>
+ <string name="tethering_settings_not_available" msgid="266821736434699780">"Подешавања привезивања нису доступна за овог корисника"</string>
+ <string name="apn_settings_not_available" msgid="1147111671403342300">"Подешавања назива приступне тачке нису доступна за овог корисника"</string>
+ <string name="enable_adb" msgid="8072776357237289039">"Отклањање USB грешака"</string>
+ <string name="enable_adb_summary" msgid="3711526030096574316">"Режим отклањања грешака када је USB повезан"</string>
+ <string name="clear_adb_keys" msgid="3010148733140369917">"Опозивање одобрења за уклањање USB грешака"</string>
+ <string name="enable_adb_wireless" msgid="6973226350963971018">"Бежично отклањање грешака"</string>
+ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим за отклањање грешака када је Wi‑Fi повезан"</string>
+ <string name="adb_wireless_error" msgid="721958772149779856">"Грешка"</string>
+ <string name="adb_wireless_settings" msgid="2295017847215680229">"Бежично отклањање грешака"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Да бисте видели и користили доступне уређаје, укључите бежично отклањање грешака"</string>
+ <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Упарите уређај помоћу QR кода"</string>
+ <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Упарите нове уређаје помоћу читача QR кода"</string>
+ <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Упарите уређај помоћу кода за упаривање"</string>
+ <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Упарите нове уређаје помоћу шестоцифреног кода"</string>
+ <string name="adb_paired_devices_title" msgid="5268997341526217362">"Упарени уређаји"</string>
+ <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Тренутно је повезано"</string>
+ <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Детаљи о уређају"</string>
+ <string name="adb_device_forget" msgid="193072400783068417">"Заборави"</string>
+ <string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Отисак прста на уређају: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
+ <string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Повезивање није успело"</string>
+ <string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Уверите се да је <xliff:g id="DEVICE_NAME">%1$s</xliff:g> повезан са одговарајућом мрежом"</string>
+ <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Упарите са уређајем"</string>
+ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Кôд за упаривање преко Wi‑Fi-ја"</string>
+ <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Упаривање није успело"</string>
+ <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Уверите се да је уређај повезан на исту мрежу."</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Упарите уређај помоћу Wi‑Fi мреже или тако што ћете скенирати QR кôд"</string>
+ <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Упарује се уређај…"</string>
+ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Упаривање уређаја није успело. QR кôд је погрешан или уређај није повезан са истом мрежом."</string>
+ <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP адреса и порт"</string>
+ <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Скенирај QR кôд"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Упарите уређај помоћу Wi‑Fi мреже тако што ћете скенирати QR кôд"</string>
+ <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Повежите се на WiFi мрежу"</string>
+ <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отклањање грешака, програмер"</string>
+ <string name="bugreport_in_power" msgid="8664089072534638709">"Пречица за извештај о грешкама"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Приказује дугме у менију дугмета за укључивање за прављење извештаја о грешкама"</string>
+ <string name="keep_screen_on" msgid="1187161672348797558">"Не закључавај"</string>
+ <string name="keep_screen_on_summary" msgid="1510731514101925829">"Екран неће бити у режиму спавања током пуњења"</string>
+ <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Омогући snoop евид. за Bluetooth HCI"</string>
+ <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Сними Bluetooth пакете. (Укључите/искључите Bluetooth када промените ово подешавање)"</string>
+ <string name="oem_unlock_enable" msgid="5334869171871566731">"Откључавање OEM-a"</string>
+ <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Дозволи откључавање функције за покретање"</string>
+ <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Желите ли да дозволите откључавање произвођача оригиналне опреме (OEM)?"</string>
+ <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"УПОЗОРЕЊЕ: Функције за заштиту уређаја неће функционисати на овом уређају док је ово подешавање укључено."</string>
+ <string name="mock_location_app" msgid="6269380172542248304">"Изаберите апликацију за лажну локацију"</string>
+ <string name="mock_location_app_not_set" msgid="6972032787262831155">"Апликација за лажну локацију није подешена"</string>
+ <string name="mock_location_app_set" msgid="4706722469342913843">"Апликација за лажну локацију: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="debug_networking_category" msgid="6829757985772659599">"Умрежавање"</string>
+ <string name="wifi_display_certification" msgid="1805579519992520381">"Сертификација бежичног екрана"</string>
+ <string name="wifi_verbose_logging" msgid="1785910450009679371">"Омогући детаљнију евиденцију за Wi‑Fi"</string>
+ <string name="wifi_scan_throttling" msgid="2985624788509913617">"Успоравање WiFi скенирања"</string>
+ <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Насумично разврставање MAC адреса по WiFi-ју са прекидима"</string>
+ <string name="mobile_data_always_on" msgid="8275958101875563572">"Мобилни подаци су увек активни"</string>
+ <string name="tethering_hardware_offload" msgid="4116053719006939161">"Хардверско убрзање привезивања"</string>
+ <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Прикажи Bluetooth уређаје без назива"</string>
+ <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Онемогући главно подешавање јачине звука"</string>
+ <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Омогући Gabeldorsche"</string>
+ <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Верзија Bluetooth AVRCP-а"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Изаберите верзију Bluetooth AVRCP-а"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Верзија Bluetooth MAP-а"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Изаберите верзију Bluetooth MAP-а"</string>
+ <string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth аудио кодек"</string>
+ <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Изаберите Bluetooth аудио кодек\n"</string>
+ <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Брзина узорковања за Bluetooth аудио"</string>
+ <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"Изаберите Bluetooth аудио кодек:\n брзина узорковања"</string>
+ <string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"Ако је нека ставка засивљена, то значи да је телефон или слушалице не подржавају"</string>
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"Битова по узорку за Bluetooth аудио"</string>
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"Изаберите Bluetooth аудио кодек:\n број битова по узорку"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"Режим канала за Bluetooth аудио"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"Изаберите Bluetooth аудио кодек:\n режим канала"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"Bluetooth аудио кодек LDAC: квалитет репродукције"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Изаберите Bluetooth аудио LDAC кодек:\n квалитет снимка"</string>
+ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Стримовање: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+ <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Приватни DNS"</string>
+ <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Изаберите режим приватног DNS-а"</string>
+ <string name="private_dns_mode_off" msgid="7065962499349997041">"Искључено"</string>
+ <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Аутоматски"</string>
+ <string name="private_dns_mode_provider" msgid="3619040641762557028">"Име хоста добављача услуге приватног DNS-а"</string>
+ <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Унесите име хоста добављача услуге DNS-а"</string>
+ <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Повезивање није успело"</string>
+ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Приказује опције за сертификацију бежичног екрана"</string>
+ <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Повећава ниво евидентирања за Wi‑Fi. Приказ по SSID RSSI-у у бирачу Wi‑Fi мреже"</string>
+ <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Смањује потрошњу батерије и побољшава учинак мреже"</string>
+ <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Када је овај режим омогућен, MAC адреса овог уређаја може да се промени сваки пут када се повеже са мрежом на којој је омогућено насумично разврставање MAC адреса."</string>
+ <string name="wifi_metered_label" msgid="8737187690304098638">"Са ограничењем"</string>
+ <string name="wifi_unmetered_label" msgid="6174142840934095093">"Без ограничења"</string>
+ <string name="select_logd_size_title" msgid="1604578195914595173">"Величине бафера података у програму за евидентирање"</string>
+ <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Изаберите величине по баферу евиденције"</string>
+ <string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Желите ли да обришете стални меморијски простор програма за евидентирање?"</string>
+ <string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Када их више не надгледамо помоћу сталног програма за евидентирање, дужни смо да обришемо податке из програма за евидентирање који су трајно смештени на уређају."</string>
+ <string name="select_logpersist_title" msgid="447071974007104196">"Чувај евидентиране податке на уређају"</string>
+ <string name="select_logpersist_dialog_title" msgid="7745193591195485594">"Изаберите међумеморије евиденције које ћете стално чувати на уређају."</string>
+ <string name="select_usb_configuration_title" msgid="6339801314922294586">"Изаберите конфигурацију USB-а"</string>
+ <string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Изаберите конфигурацију USB-а"</string>
+ <string name="allow_mock_location" msgid="2102650981552527884">"Дозволи лажне локације"</string>
+ <string name="allow_mock_location_summary" msgid="179780881081354579">"Дозволи лажне локације"</string>
+ <string name="debug_view_attributes" msgid="3539609843984208216">"Омогући проверу атрибута за преглед"</string>
+ <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Мобилни подаци су увек активни, чак и када је Wi‑Fi активан (ради брзе промене мреже)."</string>
+ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Користи се хардверско убрзање привезивања ако је доступно"</string>
+ <string name="adb_warning_title" msgid="7708653449506485728">"Дозволи отклањање USB грешака?"</string>
+ <string name="adb_warning_message" msgid="8145270656419669221">"Отклањање USB грешака намењено је само за сврхе програмирања. Користите га за копирање података са рачунара на уређај и обратно, инсталирање апликација на уређају без обавештења и читање података из евиденције."</string>
+ <string name="adbwifi_warning_title" msgid="727104571653031865">"Желите да дозволите бежично отклањање грешака?"</string>
+ <string name="adbwifi_warning_message" msgid="8005936574322702388">"Бежично отклањање грешака намењено је само програмирању. Користите га за копирање података са рачунара на уређај и обратно, инсталирање апликација на уређају без обавештења и читање података из евиденције."</string>
+ <string name="adb_keys_warning_message" msgid="2968555274488101220">"Желите ли да опозовете приступ отклањању USB грешака са свих рачунара које сте претходно одобрили?"</string>
+ <string name="dev_settings_warning_title" msgid="8251234890169074553">"Желите ли да омогућите програмерска подешавања?"</string>
+ <string name="dev_settings_warning_message" msgid="37741686486073668">"Ова подешавања су намењена само за програмирање. Могу да изазову престанак функционисања или неочекивано понашање уређаја и апликација на њему."</string>
+ <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Верификуј апликације преко USB-а"</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Проверава да ли су апликације инсталиране преко ADB-а/ADT-а штетне."</string>
+ <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Приказује Bluetooth уређаје без назива (само MAC адресе)"</string>
+ <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Онемогућава главно подешавање јачине звука на Bluetooth уређају у случају проблема са јачином звука на даљинским уређајима, као што су изузетно велика јачина звука или недостатак контроле."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Омогућава групу Bluetooth Gabeldorsche функција."</string>
+ <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Омогућава функцију Побољшано повезивање."</string>
+ <string name="enable_terminal_title" msgid="3834790541986303654">"Локални терминал"</string>
+ <string name="enable_terminal_summary" msgid="2481074834856064500">"Омогући апл. терминала за приступ локалном командном окружењу"</string>
+ <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP провера"</string>
+ <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Подешавање понашања HDCP провере"</string>
+ <string name="debug_debugging_category" msgid="535341063709248842">"Отклањање грешака"</string>
+ <string name="debug_app" msgid="8903350241392391766">"Изаберите апликацију за отклањање грешака"</string>
+ <string name="debug_app_not_set" msgid="1934083001283807188">"Нема подешених апликација за отклањање грешака"</string>
+ <string name="debug_app_set" msgid="6599535090477753651">"Апликација за отклањање грешака: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="select_application" msgid="2543228890535466325">"Бирање апликације"</string>
+ <string name="no_application" msgid="9038334538870247690">"Ниједна"</string>
+ <string name="wait_for_debugger" msgid="7461199843335409809">"Сачекај програм за отклањање грешака"</string>
+ <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Апликација чека програм за отклањање грешака да приложи пре извршавања"</string>
+ <string name="debug_input_category" msgid="7349460906970849771">"Унос"</string>
+ <string name="debug_drawing_category" msgid="5066171112313666619">"Цртање"</string>
+ <string name="debug_hw_drawing_category" msgid="5830815169336975162">"Хардверски убрзано приказивање"</string>
+ <string name="media_category" msgid="8122076702526144053">"Медији"</string>
+ <string name="debug_monitoring_category" msgid="1597387133765424994">"Надгледање"</string>
+ <string name="strict_mode" msgid="889864762140862437">"Омогућен је строги режим"</string>
+ <string name="strict_mode_summary" msgid="1838248687233554654">"Екран трепери када апликације обављају дуге операције на главној нити"</string>
+ <string name="pointer_location" msgid="7516929526199520173">"Локација показивача"</string>
+ <string name="pointer_location_summary" msgid="957120116989798464">"Преклопни елемент са тренутним подацима о додиру"</string>
+ <string name="show_touches" msgid="8437666942161289025">"Приказуј додире"</string>
+ <string name="show_touches_summary" msgid="3692861665994502193">"Приказује визуелне повратне информације за додире"</string>
+ <string name="show_screen_updates" msgid="2078782895825535494">"Прикажи ажурирања површине"</string>
+ <string name="show_screen_updates_summary" msgid="2126932969682087406">"Осветљава све површине прозора када се ажурирају"</string>
+ <string name="show_hw_screen_updates" msgid="2021286231267747506">"Прикажи ажурирања приказа"</string>
+ <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Осветљава приказе у прозорима када се црта"</string>
+ <string name="show_hw_layers_updates" msgid="5268370750002509767">"Прикажи ажурирања хардверских слојева"</string>
+ <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Хардверски слојеви трепере зелено када се ажурирају"</string>
+ <string name="debug_hw_overdraw" msgid="8944851091008756796">"Отклони грешке GPU преклапања"</string>
+ <string name="disable_overlays" msgid="4206590799671557143">"Онемогући HW постављене елементе"</string>
+ <string name="disable_overlays_summary" msgid="1954852414363338166">"Увек се користи GPU за компоновање екрана"</string>
+ <string name="simulate_color_space" msgid="1206503300335835151">"Симулирај простор боје"</string>
+ <string name="enable_opengl_traces_title" msgid="4638773318659125196">"Омогући OpenGL трагове"</string>
+ <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Онемогући USB преусм. звука"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Онемогућава аутоматско преусмеравање на USB аудио периферне уређаје"</string>
+ <string name="debug_layout" msgid="1659216803043339741">"Прикажи границе распореда"</string>
+ <string name="debug_layout_summary" msgid="8825829038287321978">"Приказује границе клипа, маргине итд."</string>
+ <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Наметни смер распореда здесна налево"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Намеће смер распореда екрана здесна налево за све локалитете"</string>
+ <string name="window_blurs" msgid="6831008984828425106">"Дозволи замагљења прозора"</string>
+ <string name="force_msaa" msgid="4081288296137775550">"Наметни 4x MSAA"</string>
+ <string name="force_msaa_summary" msgid="9070437493586769500">"Омогућава 4x MSAA у OpenGL ES 2.0 апликацијама"</string>
+ <string name="show_non_rect_clip" msgid="7499758654867881817">"Отклони грешке исецања области неправоугаоног облика"</string>
+ <string name="track_frame_time" msgid="522674651937771106">"Рендеруј помоћу HWUI-а"</string>
+ <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Омогући слојеве за отклањање грешака GPU-a"</string>
+ <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Учитава отклањање грешака GPU-a у апл. за отклањање грешака"</string>
+ <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Опширне евиденције продавца"</string>
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Уврштава у извештаје о грешкама додатне посебне евиденције продавца за уређаје, које могу да садрже приватне податке, да троше више батерије и/или да користе више меморије."</string>
+ <string name="window_animation_scale_title" msgid="5236381298376812508">"Размера анимације прозора"</string>
+ <string name="transition_animation_scale_title" msgid="1278477690695439337">"Размера анимације прелаза"</string>
+ <string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматорова размера трајања"</string>
+ <string name="overlay_display_devices_title" msgid="5411894622334469607">"Симулирај секундарне екране"</string>
+ <string name="debug_applications_category" msgid="5394089406638954196">"Апликације"</string>
+ <string name="immediately_destroy_activities" msgid="1826287490705167403">"Не чувај активности"</string>
+ <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Уништава сваку активност чим је корисник напусти"</string>
+ <string name="app_process_limit_title" msgid="8361367869453043007">"Ограничење позадинских процеса"</string>
+ <string name="show_all_anrs" msgid="9160563836616468726">"Прикажи ANR-ове у позадини"</string>
+ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Приказује дијалог Апликација не реагује за апликације у позадини"</string>
+ <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Приказуј упозорења због канала за обавештења"</string>
+ <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Приказује упозорење на екрану када апликација постави обавештење без важећег канала"</string>
+ <string name="force_allow_on_external" msgid="9187902444231637880">"Принудно дозволи апликације у спољној"</string>
+ <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Омогућава уписивање свих апликација у спољну меморију, без обзира на вредности манифеста"</string>
+ <string name="force_resizable_activities" msgid="7143612144399959606">"Принудно омогући промену величине активности"</string>
+ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Омогућава промену величине свих активности за режим са више прозора, без обзира на вредности манифеста."</string>
+ <string name="enable_freeform_support" msgid="7599125687603914253">"Омогући прозоре произвољног формата"</string>
+ <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Омогућава подршку за експерименталне прозоре произвољног формата."</string>
+ <string name="desktop_mode" msgid="2389067840550544462">"Режим за рачунаре"</string>
+ <string name="local_backup_password_title" msgid="4631017948933578709">"Лозинка резервне копије за рачунар"</string>
+ <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Резервне копије читавог система тренутно нису заштићене"</string>
+ <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Додирните да бисте променили или уклонили лозинку за прављење резервних копија читавог система на рачунару"</string>
+ <string name="local_backup_password_toast_success" msgid="4891666204428091604">"Постављена је нова лозинка резервне копије"</string>
+ <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"Нова лозинка и њена потврда се не подударају"</string>
+ <string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"Постављање лозинке резервне копије није успело"</string>
+ <string name="loading_injected_setting_summary" msgid="8394446285689070348">"Учитава се…"</string>
<string-array name="color_mode_names">
- <item msgid="3836559907767149216">"Živopisan (podrazumevano)"</item>
- <item msgid="9112200311983078311">"Prirodan"</item>
- <item msgid="6564241960833766170">"Standardan"</item>
+ <item msgid="3836559907767149216">"Живописан (подразумевано)"</item>
+ <item msgid="9112200311983078311">"Природан"</item>
+ <item msgid="6564241960833766170">"Стандардан"</item>
</string-array>
<string-array name="color_mode_descriptions">
- <item msgid="6828141153199944847">"Poboljšane boje"</item>
- <item msgid="4548987861791236754">"Prirodne boje nalik onima koje registruje oko"</item>
- <item msgid="1282170165150762976">"Boje optimizovane za digitalni sadržaj"</item>
+ <item msgid="6828141153199944847">"Побољшане боје"</item>
+ <item msgid="4548987861791236754">"Природне боје налик онима које региструје око"</item>
+ <item msgid="1282170165150762976">"Боје оптимизоване за дигитални садржај"</item>
</string-array>
- <string name="inactive_apps_title" msgid="5372523625297212320">"Aplikacije u stanju pripravnosti"</string>
- <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Neaktivna. Dodirnite da biste je aktivirali."</string>
- <string name="inactive_app_active_summary" msgid="8047630990208722344">"Aktivna. Dodirnite da biste je deaktivirali."</string>
- <string name="standby_bucket_summary" msgid="5128193447550429600">"Stanje pripravnosti aplikacije: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <string name="transcode_settings_title" msgid="2581975870429850549">"Podešavanja transkodiranja medija"</string>
- <string name="transcode_user_control" msgid="6176368544817731314">"Zameni podrazumevana podešavanja transkodiranja"</string>
- <string name="transcode_enable_all" msgid="2411165920039166710">"Omogući transkodiranje"</string>
- <string name="transcode_default" msgid="3784803084573509491">"Podrazumevaj da aplikacije podržavaju moderne formate"</string>
- <string name="transcode_notification" msgid="5560515979793436168">"Prikazuj obaveštenja o transkodiranju"</string>
- <string name="transcode_disable_cache" msgid="3160069309377467045">"Onemogući keš transkodiranja"</string>
- <string name="runningservices_settings_title" msgid="6460099290493086515">"Pokrenute usluge"</string>
- <string name="runningservices_settings_summary" msgid="1046080643262665743">"Prikaz i kontrola trenutno pokrenutih usluga"</string>
- <string name="select_webview_provider_title" msgid="3917815648099445503">"Primena WebView-a"</string>
- <string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Podesite primenu WebView-a"</string>
- <string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Ovaj izbor više nije važeći. Probajte ponovo."</string>
- <string name="picture_color_mode" msgid="1013807330552931903">"Režim boja slika"</string>
- <string name="picture_color_mode_desc" msgid="151780973768136200">"Koristi sRGB"</string>
- <string name="daltonizer_mode_disabled" msgid="403424372812399228">"Onemogućeno je"</string>
- <string name="daltonizer_mode_monochromacy" msgid="362060873835885014">"Jednobojnost"</string>
- <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomalija (crveno-zeleno)"</string>
- <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalija (crveno-zeleno)"</string>
- <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalija (plavo-žuto)"</string>
- <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Korekcija boja"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Korekcija boja može da bude korisna kada želite:<br/> <ol> <li>&nbsp;Preciznije da vidite boje</li> <li>&nbsp;Da uklonite boje kako biste se fokusirali</li> </ol>"</string>
- <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <string name="inactive_apps_title" msgid="5372523625297212320">"Апликације у стању приправности"</string>
+ <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Неактивна. Додирните да бисте је активирали."</string>
+ <string name="inactive_app_active_summary" msgid="8047630990208722344">"Активна. Додирните да бисте је деактивирали."</string>
+ <string name="standby_bucket_summary" msgid="5128193447550429600">"Стање приправности апликације: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
+ <string name="transcode_settings_title" msgid="2581975870429850549">"Подешавања транскодирања медија"</string>
+ <string name="transcode_user_control" msgid="6176368544817731314">"Замени подразумевана подешавања транскодирања"</string>
+ <string name="transcode_enable_all" msgid="2411165920039166710">"Омогући транскодирање"</string>
+ <string name="transcode_default" msgid="3784803084573509491">"Подразумевај да апликације подржавају модерне формате"</string>
+ <string name="transcode_notification" msgid="5560515979793436168">"Приказуј обавештења о транскодирању"</string>
+ <string name="transcode_disable_cache" msgid="3160069309377467045">"Онемогући кеш транскодирања"</string>
+ <string name="runningservices_settings_title" msgid="6460099290493086515">"Покренуте услуге"</string>
+ <string name="runningservices_settings_summary" msgid="1046080643262665743">"Приказ и контрола тренутно покренутих услуга"</string>
+ <string name="select_webview_provider_title" msgid="3917815648099445503">"Примена WebView-а"</string>
+ <string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Подесите примену WebView-а"</string>
+ <string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Овај избор више није важећи. Пробајте поново."</string>
+ <string name="picture_color_mode" msgid="1013807330552931903">"Режим боја слика"</string>
+ <string name="picture_color_mode_desc" msgid="151780973768136200">"Користи sRGB"</string>
+ <string name="daltonizer_mode_disabled" msgid="403424372812399228">"Онемогућено је"</string>
+ <string name="daltonizer_mode_monochromacy" msgid="362060873835885014">"Једнобојност"</string>
+ <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Деутераномалија (црвено-зелено)"</string>
+ <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалија (црвено-зелено)"</string>
+ <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалија (плаво-жуто)"</string>
+ <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекција боја"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Корекција боја може да буде корисна када желите:<br/> <ol> <li>&nbsp;Прецизније да видите боје</li> <li>&nbsp;Да уклоните боје како бисте се фокусирали</li> </ol>"</string>
+ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>–<xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
- <string name="power_remaining_duration_only" msgid="8264199158671531431">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
- <string name="power_discharging_duration" msgid="1076561255466053220">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na osnovu korišćenja"</string>
- <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na osnovu korišćenja (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_only" msgid="8264199158671531431">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
+ <string name="power_discharging_duration" msgid="1076561255466053220">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> на основу коришћења"</string>
+ <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> на основу коришћења (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<!-- no translation found for power_remaining_duration_only_short (7438846066602840588) -->
<skip />
- <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g> na osnovu korišćenja (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g> na osnovu korišćenja"</string>
- <string name="power_discharge_by" msgid="4113180890060388350">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only" msgid="92545648425937000">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija će se možda isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Još manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
- <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Još manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Još više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Još više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
- <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon će se uskoro isključiti"</string>
- <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet će se uskoro isključiti"</string>
- <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj će se uskoro isključiti"</string>
- <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="4429259621177089719">"Telefon će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
- <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Tablet će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
- <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Uređaj će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+ <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g> на основу коришћења (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g> на основу коришћења"</string>
+ <string name="power_discharge_by" msgid="4113180890060388350">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only" msgid="92545648425937000">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батерија ће се можда испразнити до <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Још мање од <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Још мање од <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Још више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Још више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
+ <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон ће се ускоро искључити"</string>
+ <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Таблет ће се ускоро искључити"</string>
+ <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Уређај ће се ускоро искључити"</string>
+ <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="4429259621177089719">"Телефон ће се ускоро искључити (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Таблет ће се ускоро искључити (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Уређај ће се ускоро искључити (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do kraja punjenja"</string>
- <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do kraja punjenja"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Punjenje je pauzirano"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje do <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
- <string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string>
- <string name="battery_info_status_charging" msgid="4279958015430387405">"Puni se"</string>
- <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo se puni"</string>
- <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Sporo se puni"</string>
- <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Bežično punjenje"</string>
- <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Punjenje"</string>
- <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string>
- <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, ne puni se"</string>
- <string name="battery_info_status_full" msgid="1339002294876531312">"Napunjeno"</string>
- <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Napunjeno do kraja"</string>
- <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontroliše administrator"</string>
- <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolišu ograničena podešavanja"</string>
- <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
- <string name="external_source_trusted" msgid="1146522036773132905">"Dozvoljeno"</string>
- <string name="external_source_untrusted" msgid="5037891688911672227">"Nije dozvoljeno"</string>
- <string name="install_other_apps" msgid="3232595082023199454">"Instaliranje nepoznatih aplikacija"</string>
- <string name="home" msgid="973834627243661438">"Početna za Podešavanja"</string>
+ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до краја пуњења"</string>
+ <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до краја пуњења"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
+ <string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string>
+ <string name="battery_info_status_charging" msgid="4279958015430387405">"Пуни се"</string>
+ <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо се пуни"</string>
+ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Споро се пуни"</string>
+ <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Бежично пуњење"</string>
+ <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Пуњење"</string>
+ <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не пуни се"</string>
+ <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Повезано, не пуни се"</string>
+ <string name="battery_info_status_full" msgid="1339002294876531312">"Напуњено"</string>
+ <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Напуњено до краја"</string>
+ <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролише администратор"</string>
+ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролишу ограничена подешавања"</string>
+ <string name="disabled" msgid="8017887509554714950">"Онемогућено"</string>
+ <string name="external_source_trusted" msgid="1146522036773132905">"Дозвољено"</string>
+ <string name="external_source_untrusted" msgid="5037891688911672227">"Није дозвољено"</string>
+ <string name="install_other_apps" msgid="3232595082023199454">"Инсталирање непознатих апликација"</string>
+ <string name="home" msgid="973834627243661438">"Почетна за Подешавања"</string>
<string-array name="battery_labels">
<item msgid="7878690469765357158">"0%"</item>
<item msgid="8894873528875953317">"50%"</item>
<item msgid="7529124349186240216">"100%"</item>
</string-array>
- <string name="charge_length_format" msgid="6941645744588690932">"Pre <xliff:g id="ID_1">%1$s</xliff:g>"</string>
- <string name="remaining_length_format" msgid="4310625772926171089">"Još <xliff:g id="ID_1">%1$s</xliff:g>"</string>
- <string name="screen_zoom_summary_small" msgid="6050633151263074260">"Mali"</string>
- <string name="screen_zoom_summary_default" msgid="1888865694033865408">"Podrazumevano"</string>
- <string name="screen_zoom_summary_large" msgid="4706951482598978984">"Veliki"</string>
- <string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"Veći"</string>
- <string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"Najveći"</string>
- <string name="screen_zoom_summary_custom" msgid="3468154096832912210">"Prilagođeni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
- <string name="content_description_menu_button" msgid="6254844309171779931">"Meni"</string>
- <string name="retail_demo_reset_message" msgid="5392824901108195463">"Unesite lozinku da biste obavili resetovanje na fabrička podešavanja u režimu demonstracije"</string>
- <string name="retail_demo_reset_next" msgid="3688129033843885362">"Dalje"</string>
- <string name="retail_demo_reset_title" msgid="1866911701095959800">"Potrebna je lozinka"</string>
- <string name="active_input_method_subtypes" msgid="4232680535471633046">"Metode aktivnog unosa"</string>
- <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Koristi jezike sistema"</string>
- <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Otvaranje podešavanja za aplikaciju <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> nije uspelo"</string>
- <string name="ime_security_warning" msgid="6547562217880551450">"Ovaj metod unosa možda može da prikuplja sav tekst koji unosite, uključujući lične podatke, kao što su lozinke i brojevi kreditnih kartica. Potiče od aplikacije <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Želite li da koristite ovaj metod unosa?"</string>
- <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Napomena: Posle restartovanja ova aplikacija ne može da se pokrene dok ne otključate telefon"</string>
- <string name="ims_reg_title" msgid="8197592958123671062">"Status IMS registracije"</string>
- <string name="ims_reg_status_registered" msgid="884916398194885457">"Registrovan je"</string>
- <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Nije registrovan"</string>
- <string name="status_unavailable" msgid="5279036186589861608">"Nedostupno"</string>
- <string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC adresa je nasumično izabrana"</string>
- <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 uređaja je povezano}=1{1 uređaj je povezan}one{# uređaj je povezan}few{# uređaja su povezana}other{# uređaja je povezano}}"</string>
- <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Više vremena."</string>
- <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Manje vremena."</string>
- <string name="cancel" msgid="5665114069455378395">"Otkaži"</string>
- <string name="okay" msgid="949938843324579502">"Potvrdi"</string>
- <string name="done" msgid="381184316122520313">"Gotovo"</string>
- <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmi i podsetnici"</string>
- <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Omogući podešavanje alarma i podsetnika"</string>
- <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsetnici"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite ovoj aplikaciji da podešava alarme i zakazuje vremenski osetljive radnje. To omogućava da aplikacija bude pokrenuta u pozadini, što može da troši više baterije.\n\nAko je ova dozvola isključena, postojeći alarmi i događaji zasnovani na vremenu zakazani pomoću ove aplikacije neće raditi."</string>
- <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"zakazati, alarm, podsetnik, sat"</string>
- <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
- <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite režim Ne uznemiravaj"</string>
- <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikad"</string>
- <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Samo prioritetni prekidi"</string>
+ <string name="charge_length_format" msgid="6941645744588690932">"Пре <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="remaining_length_format" msgid="4310625772926171089">"Још <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="screen_zoom_summary_small" msgid="6050633151263074260">"Мали"</string>
+ <string name="screen_zoom_summary_default" msgid="1888865694033865408">"Подразумевано"</string>
+ <string name="screen_zoom_summary_large" msgid="4706951482598978984">"Велики"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"Већи"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"Највећи"</string>
+ <string name="screen_zoom_summary_custom" msgid="3468154096832912210">"Прилагођени (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
+ <string name="content_description_menu_button" msgid="6254844309171779931">"Мени"</string>
+ <string name="retail_demo_reset_message" msgid="5392824901108195463">"Унесите лозинку да бисте обавили ресетовање на фабричка подешавања у режиму демонстрације"</string>
+ <string name="retail_demo_reset_next" msgid="3688129033843885362">"Даље"</string>
+ <string name="retail_demo_reset_title" msgid="1866911701095959800">"Потребна је лозинка"</string>
+ <string name="active_input_method_subtypes" msgid="4232680535471633046">"Методе активног уноса"</string>
+ <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Користи језике система"</string>
+ <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Отварање подешавања за апликацију <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> није успело"</string>
+ <string name="ime_security_warning" msgid="6547562217880551450">"Овај метод уноса можда може да прикупља сав текст који уносите, укључујући личне податке, као што су лозинке и бројеви кредитних картица. Потиче од апликације <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Желите ли да користите овај метод уноса?"</string>
+ <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Напомена: После рестартовања ова апликација не може да се покрене док не откључате телефон"</string>
+ <string name="ims_reg_title" msgid="8197592958123671062">"Статус IMS регистрације"</string>
+ <string name="ims_reg_status_registered" msgid="884916398194885457">"Регистрован je"</string>
+ <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Није регистрован"</string>
+ <string name="status_unavailable" msgid="5279036186589861608">"Недоступно"</string>
+ <string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC адреса је насумично изабрана"</string>
+ <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 уређаја је повезано}=1{1 уређај је повезан}one{# уређај је повезан}few{# уређаја су повезана}other{# уређаја је повезано}}"</string>
+ <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Више времена."</string>
+ <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Мање времена."</string>
+ <string name="cancel" msgid="5665114069455378395">"Откажи"</string>
+ <string name="okay" msgid="949938843324579502">"Потврди"</string>
+ <string name="done" msgid="381184316122520313">"Готово"</string>
+ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Аларми и подсетници"</string>
+ <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Омогући подешавање аларма и подсетника"</string>
+ <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Аларми и подсетници"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Омогућите овој апликацији да подешава аларме и заказује временски осетљиве радње. То омогућава да апликација буде покренута у позадини, што може да троши више батерије.\n\nАко је ова дозвола искључена, постојећи аларми и догађаји засновани на времену заказани помоћу ове апликације неће радити."</string>
+ <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"заказати, аларм, подсетник, сат"</string>
+ <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Укључи"</string>
+ <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Укључите режим Не узнемиравај"</string>
+ <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никад"</string>
+ <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Само приоритетни прекиди"</string>
<string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Nećete čuti sledeći alarm u <xliff:g id="WHEN">%1$s</xliff:g> ako ne isključite ovo pre toga"</string>
- <string name="zen_alarm_warning" msgid="245729928048586280">"Nećete čuti sledeći alarm u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="alarm_template" msgid="3346777418136233330">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Нећете чути следећи аларм у <xliff:g id="WHEN">%1$s</xliff:g> ако не искључите ово пре тога"</string>
+ <string name="zen_alarm_warning" msgid="245729928048586280">"Нећете чути следећи аларм у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="alarm_template" msgid="3346777418136233330">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="6382760514842998629">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
- <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pitaj svaki put"</string>
- <string name="zen_mode_forever" msgid="3339224497605461291">"Dok ne isključite"</string>
- <string name="time_unit_just_now" msgid="3006134267292728099">"Upravo"</string>
- <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ovaj telefon"</string>
- <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ovaj tablet"</string>
- <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
- <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem pri povezivanju. Isključite uređaj, pa ga ponovo uključite"</string>
- <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
- <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
- <string name="storage_category" msgid="2287342585424631813">"Memorijski prostor"</string>
- <string name="shared_data_title" msgid="1017034836800864953">"Deljeni podaci"</string>
- <string name="shared_data_summary" msgid="5516326713822885652">"Pregledajte i izmenite deljene podatke"</string>
- <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Nema deljenih podataka za ovog korisnika."</string>
- <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Došlo je do greške pri preuzimanju deljenih podataka. Probajte ponovo."</string>
- <string name="blob_id_text" msgid="8680078988996308061">"ID deljenih podataka: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
- <string name="blob_expires_text" msgid="7882727111491739331">"Ističe: <xliff:g id="DATE">%s</xliff:g>"</string>
- <string name="shared_data_delete_failure_text" msgid="3842701391009628947">"Došlo je do greške pri brisanju deljenih podataka."</string>
- <string name="shared_data_no_accessors_dialog_text" msgid="8903738462570715315">"Nema kupljenih zakupa za ove deljene podatke. Želite li da ih izbrišete?"</string>
- <string name="accessor_info_title" msgid="8289823651512477787">"Aplikacije koje dele podatke"</string>
- <string name="accessor_no_description_text" msgid="7510967452505591456">"U aplikaciji nije naveden nijedan opis."</string>
- <string name="accessor_expires_text" msgid="4625619273236786252">"Iznajmljivanje ističe: <xliff:g id="DATE">%s</xliff:g>"</string>
- <string name="delete_blob_text" msgid="2819192607255625697">"Izbriši deljene podatke"</string>
- <string name="delete_blob_confirmation_text" msgid="7807446938920827280">"Želite li stvarno da izbrišete ove deljene podatke?"</string>
- <string name="user_add_user_item_summary" msgid="5748424612724703400">"Korisnici imaju sopstvene aplikacije i sadržaj"</string>
- <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Možete da ograničite pristup na aplikacije i sadržaj sa naloga"</string>
- <string name="user_add_user_item_title" msgid="2394272381086965029">"Korisnik"</string>
- <string name="user_add_profile_item_title" msgid="3111051717414643029">"Ograničeni profil"</string>
- <string name="user_add_user_title" msgid="5457079143694924885">"Dodajete novog korisnika?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Ovaj uređaj možete da delite sa drugim ljudima ako napravite još korisnika. Svaki korisnik ima sopstveni prostor, koji može da prilagođava pomoću aplikacija, pozadine i slično. Korisnici mogu da prilagođavaju i podešavanja uređaja koja utiču na svakoga, poput Wi‑Fi-ja.\n\nKada dodate novog korisnika, ta osoba treba da podesi sopstveni prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike. Podešavanja i usluge pristupačnosti ne mogu da se prenose na novog korisnika."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Kada dodate novog korisnika, ta osoba treba da podesi sopstveni prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
- <string name="user_setup_dialog_title" msgid="8037342066381939995">"Podešavate korisnika?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"Ta osoba treba da uzme uređaj i podesi svoj prostor"</string>
- <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Želite li da odmah podesite profil?"</string>
- <string name="user_setup_button_setup_now" msgid="1708269547187760639">"Podesi"</string>
- <string name="user_setup_button_setup_later" msgid="8712980133555493516">"Ne sada"</string>
- <string name="user_add_user_type_title" msgid="551279664052914497">"Dodavanje"</string>
- <string name="user_new_user_name" msgid="60979820612818840">"Novi korisnik"</string>
- <string name="user_new_profile_name" msgid="2405500423304678841">"Novi profil"</string>
- <string name="user_info_settings_title" msgid="6351390762733279907">"Podaci o korisniku"</string>
- <string name="profile_info_settings_title" msgid="105699672534365099">"Podaci o profilu"</string>
- <string name="user_need_lock_message" msgid="4311424336209509301">"Da biste mogli da napravite ograničeni profil, treba da podesite zaključavanje ekrana da biste zaštitili aplikacije i lične podatke."</string>
- <string name="user_set_lock_button" msgid="1427128184982594856">"Podesi zaključavanje"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"Pređi na korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
- <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Pravi se novi korisnik…"</string>
- <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Pravi se novi gost…"</string>
- <string name="add_user_failed" msgid="4809887794313944872">"Pravljenje novog korisnika nije uspelo"</string>
- <string name="add_guest_failed" msgid="8074548434469843443">"Pravljenje novog gosta nije uspelo"</string>
- <string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
- <string name="user_add_user" msgid="7876449291500212468">"Dodaj korisnika"</string>
- <string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
- <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
- <string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesiju gosta"</string>
- <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Želite li da resetujete sesiju gosta?"</string>
- <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Želite da uklonite gosta?"</string>
- <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string>
- <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ukloni"</string>
- <string name="guest_resetting" msgid="7822120170191509566">"Sesija gosta se resetuje…"</string>
- <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Želite da resetujete sesiju gosta?"</string>
- <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Time ćete pokrenuti novu sesiju gosta i izbrisati sve aplikacije i podatke iz aktuelne sesije"</string>
- <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Izlazite iz režima gosta?"</string>
- <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Time ćete izbrisati sve aplikacije i podatke iz aktuelne sesije gosta"</string>
- <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Izađi"</string>
- <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Sačuvaćete aktivnosti gosta?"</string>
- <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Sačuvajte aktivnosti iz aktuelne sesije ili izbrišite sve aplikacije i podatke"</string>
- <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Izbriši"</string>
- <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Sačuvaj"</string>
- <string name="guest_exit_button" msgid="5774985819191803960">"Izađi iz režima gosta"</string>
- <string name="guest_reset_button" msgid="2515069346223503479">"Resetuj sesiju gosta"</string>
- <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Zatvori režim gosta"</string>
- <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sve aktivnosti će biti izbrisane pri izlazu"</string>
- <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete da sačuvate ili izbrišete aktivnosti pri izlazu"</string>
- <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetujete za brisanje aktivnosti sesije, ili sačuvajte ili izbrišite aktivnosti pri izlazu"</string>
- <string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string>
- <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
- <string name="user_image_photo_selector" msgid="433658323306627093">"Izaberite sliku"</string>
- <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Previše netačnih pokušaja. Izbrisaćemo podatke sa ovog uređaja."</string>
- <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Previše netačnih pokušaja. Izbrisaćemo ovog korisnika."</string>
- <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Previše netačnih pokušaja. Izbrisaćemo ovaj poslovni profil i njegove podatke."</string>
- <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Odbaci"</string>
- <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Podrazumevano za uređaj"</string>
- <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Onemogućeno"</string>
- <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
- <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate da restartujete uređaj da bi se ova promena primenila. Restartujte ga odmah ili otkažite."</string>
- <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Žičane slušalice"</string>
- <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Uključeno"</string>
- <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Isključeno"</string>
- <string name="carrier_network_change_mode" msgid="4257621815706644026">"Promena mreže mobilnog operatera"</string>
+ <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Трајање"</string>
+ <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Питај сваки пут"</string>
+ <string name="zen_mode_forever" msgid="3339224497605461291">"Док не искључите"</string>
+ <string name="time_unit_just_now" msgid="3006134267292728099">"Управо"</string>
+ <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Овај телефон"</string>
+ <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Овај таблет"</string>
+ <string name="media_transfer_this_phone" msgid="7194341457812151531">"Овај телефон"</string>
+ <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем при повезивању. Искључите уређај, па га поново укључите"</string>
+ <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичани аудио уређај"</string>
+ <string name="help_label" msgid="3528360748637781274">"Помоћ и повратне информације"</string>
+ <string name="storage_category" msgid="2287342585424631813">"Меморијски простор"</string>
+ <string name="shared_data_title" msgid="1017034836800864953">"Дељени подаци"</string>
+ <string name="shared_data_summary" msgid="5516326713822885652">"Прегледајте и измените дељене податке"</string>
+ <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Нема дељених података за овог корисника."</string>
+ <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Дошло је до грешке при преузимању дељених података. Пробајте поново."</string>
+ <string name="blob_id_text" msgid="8680078988996308061">"ИД дељених података: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
+ <string name="blob_expires_text" msgid="7882727111491739331">"Истиче: <xliff:g id="DATE">%s</xliff:g>"</string>
+ <string name="shared_data_delete_failure_text" msgid="3842701391009628947">"Дошло је до грешке при брисању дељених података."</string>
+ <string name="shared_data_no_accessors_dialog_text" msgid="8903738462570715315">"Нема купљених закупа за ове дељене податке. Желите ли да их избришете?"</string>
+ <string name="accessor_info_title" msgid="8289823651512477787">"Апликације које деле податке"</string>
+ <string name="accessor_no_description_text" msgid="7510967452505591456">"У апликацији није наведен ниједан опис."</string>
+ <string name="accessor_expires_text" msgid="4625619273236786252">"Изнајмљивање истиче: <xliff:g id="DATE">%s</xliff:g>"</string>
+ <string name="delete_blob_text" msgid="2819192607255625697">"Избриши дељене податке"</string>
+ <string name="delete_blob_confirmation_text" msgid="7807446938920827280">"Желите ли стварно да избришете ове дељене податке?"</string>
+ <string name="user_add_user_item_summary" msgid="5748424612724703400">"Корисници имају сопствене апликације и садржај"</string>
+ <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Можете да ограничите приступ на апликације и садржај са налога"</string>
+ <string name="user_add_user_item_title" msgid="2394272381086965029">"Корисник"</string>
+ <string name="user_add_profile_item_title" msgid="3111051717414643029">"Ограничени профил"</string>
+ <string name="user_add_user_title" msgid="5457079143694924885">"Додајете новог корисника?"</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Овај уређај можете да делите са другим људима ако направите још корисника. Сваки корисник има сопствени простор, који може да прилагођава помоћу апликација, позадине и слично. Корисници могу да прилагођавају и подешавања уређаја која утичу на свакога, попут Wi‑Fi-ја.\n\nКада додате новог корисника, та особа треба да подеси сопствени простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике. Подешавања и услуге приступачности не могу да се преносе на новог корисника."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Када додате новог корисника, та особа треба да подеси сопствени простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике."</string>
+ <string name="user_setup_dialog_title" msgid="8037342066381939995">"Подешавате корисника?"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"Та особа треба да узме уређај и подеси свој простор"</string>
+ <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Желите ли да одмах подесите профил?"</string>
+ <string name="user_setup_button_setup_now" msgid="1708269547187760639">"Подеси"</string>
+ <string name="user_setup_button_setup_later" msgid="8712980133555493516">"Не сада"</string>
+ <string name="user_add_user_type_title" msgid="551279664052914497">"Додавање"</string>
+ <string name="user_new_user_name" msgid="60979820612818840">"Нови корисник"</string>
+ <string name="user_new_profile_name" msgid="2405500423304678841">"Нови профил"</string>
+ <string name="user_info_settings_title" msgid="6351390762733279907">"Подаци о кориснику"</string>
+ <string name="profile_info_settings_title" msgid="105699672534365099">"Подаци о профилу"</string>
+ <string name="user_need_lock_message" msgid="4311424336209509301">"Да бисте могли да направите ограничени профил, треба да подесите закључавање екрана да бисте заштитили апликације и личне податке."</string>
+ <string name="user_set_lock_button" msgid="1427128184982594856">"Подеси закључавање"</string>
+ <string name="user_switch_to_user" msgid="6975428297154968543">"Пређи на корисника <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Прави се нови корисник…"</string>
+ <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Прави се нови гост…"</string>
+ <string name="add_user_failed" msgid="4809887794313944872">"Прављење новог корисника није успело"</string>
+ <string name="add_guest_failed" msgid="8074548434469843443">"Прављење новог госта није успело"</string>
+ <string name="user_nickname" msgid="262624187455825083">"Надимак"</string>
+ <string name="user_add_user" msgid="7876449291500212468">"Додај корисника"</string>
+ <string name="guest_new_guest" msgid="3482026122932643557">"Додај госта"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string>
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Ресетуј сесију госта"</string>
+ <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Желите ли да ресетујете сесију госта?"</string>
+ <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Желите да уклоните госта?"</string>
+ <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетуј"</string>
+ <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Уклони"</string>
+ <string name="guest_resetting" msgid="7822120170191509566">"Сесија госта се ресетује…"</string>
+ <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Желите да ресетујете сесију госта?"</string>
+ <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Тиме ћете покренути нову сесију госта и избрисати све апликације и податке из актуелне сесије"</string>
+ <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Излазите из режима госта?"</string>
+ <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Тиме ћете избрисати све апликације и податке из актуелне сесије госта"</string>
+ <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Изађи"</string>
+ <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Сачуваћете активности госта?"</string>
+ <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Сачувајте активности из актуелне сесије или избришите све апликације и податке"</string>
+ <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Избриши"</string>
+ <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Сачувај"</string>
+ <string name="guest_exit_button" msgid="5774985819191803960">"Изађи из режима госта"</string>
+ <string name="guest_reset_button" msgid="2515069346223503479">"Ресетуј сесију госта"</string>
+ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Затвори режим госта"</string>
+ <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Све активности ће бити избрисане при излазу"</string>
+ <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Можете да сачувате или избришете активности при излазу"</string>
+ <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ресетујете за брисање активности сесије, или сачувајте или избришите активности при излазу"</string>
+ <string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string>
+ <string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string>
+ <string name="user_image_photo_selector" msgid="433658323306627093">"Изаберите слику"</string>
+ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Превише нетачних покушаја. Избрисаћемо податке са овог уређаја."</string>
+ <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Превише нетачних покушаја. Избрисаћемо овог корисника."</string>
+ <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Превише нетачних покушаја. Избрисаћемо овај пословни профил и његове податке."</string>
+ <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Одбаци"</string>
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Подразумевано за уређај"</string>
+ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Онемогућено"</string>
+ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Омогућено"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Морате да рестартујете уређај да би се ова промена применила. Рестартујте га одмах или откажите."</string>
+ <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Жичане слушалице"</string>
+ <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Укључено"</string>
+ <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Искључено"</string>
+ <string name="carrier_network_change_mode" msgid="4257621815706644026">"Промена мреже мобилног оператера"</string>
<string name="data_connection_3g" msgid="931852552688157407">"3G"</string>
<string name="data_connection_edge" msgid="4625509456544797637">"EDGE"</string>
<string name="data_connection_cdma" msgid="9098161966701934334">"1X"</string>
@@ -642,34 +644,34 @@
<string name="data_connection_lte" msgid="7675461204366364124">"LTE"</string>
<string name="data_connection_lte_plus" msgid="6643158654804916653">"LTE+"</string>
<string name="data_connection_carrier_wifi" msgid="8932949159370130465">"W+"</string>
- <string name="cell_data_off_content_description" msgid="2280700839891636498">"Mobilni podaci su isključeni"</string>
- <string name="not_default_data_content_description" msgid="6517068332106592887">"Nije podešeno za korišćenje podataka"</string>
- <string name="accessibility_no_phone" msgid="2687419663127582503">"Nema telefona."</string>
- <string name="accessibility_phone_one_bar" msgid="5719721147018970063">"Signal telefona ima jednu crtu."</string>
- <string name="accessibility_phone_two_bars" msgid="2531458337458953263">"Signal telefona od dve crte."</string>
- <string name="accessibility_phone_three_bars" msgid="1523967995996696619">"Signal telefona od tri crte."</string>
- <string name="accessibility_phone_signal_full" msgid="4302338883816077134">"Signal telefona je pun."</string>
- <string name="accessibility_no_data" msgid="4563181886936931008">"Nema podataka."</string>
- <string name="accessibility_data_one_bar" msgid="6892888138070752480">"Signal za podatke ima jednu crtu."</string>
- <string name="accessibility_data_two_bars" msgid="9202641507241802499">"Signal za podatke od dve crte."</string>
- <string name="accessibility_data_three_bars" msgid="2813876214466722413">"Signal za podatke od tri crte."</string>
- <string name="accessibility_data_signal_full" msgid="1808301899314382337">"Signal za podatke je najjači."</string>
- <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Veza sa eternetom je prekinuta."</string>
- <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Eternet."</string>
- <string name="accessibility_no_calling" msgid="3540827068323895748">"Bez pozivanja."</string>
- <string name="avatar_picker_title" msgid="8492884172713170652">"Odaberite sliku profila"</string>
- <string name="default_user_icon_description" msgid="6554047177298972638">"Podrazumevana ikona korisnika"</string>
- <string name="physical_keyboard_title" msgid="4811935435315835220">"Fizička tastatura"</string>
- <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Odaberite raspored tastature"</string>
- <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Podrazumevano"</string>
- <string name="turn_screen_on_title" msgid="3266937298097573424">"Uključite ekran"</string>
- <string name="allow_turn_screen_on" msgid="6194845766392742639">"Dozvoli uključivanje ekrana"</string>
- <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Dozvoljava aplikaciji da uključi ekran. Ako se omogući, aplikacija može da uključi ekran u bilo kom trenutku bez vaše eksplicitne namere."</string>
- <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Želite da zaustavite emitovanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
- <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string>
- <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitujte aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
- <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Promenite izlaz"</string>
- <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije za pokret povratka sa predviđanjem"</string>
- <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogućite animacije sistema za pokret povratka sa predviđanjem."</string>
- <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ovo podešavanje omogućava animacije sistema za pokret povratka sa predviđanjem. Zahteva podešavanje dozvole enableOnBackInvokedCallback po aplikaciji na true u fajlu manifesta."</string>
+ <string name="cell_data_off_content_description" msgid="2280700839891636498">"Мобилни подаци су искључени"</string>
+ <string name="not_default_data_content_description" msgid="6517068332106592887">"Није подешено за коришћење података"</string>
+ <string name="accessibility_no_phone" msgid="2687419663127582503">"Нема телефона."</string>
+ <string name="accessibility_phone_one_bar" msgid="5719721147018970063">"Сигнал телефона има једну црту."</string>
+ <string name="accessibility_phone_two_bars" msgid="2531458337458953263">"Сигнал телефона од две црте."</string>
+ <string name="accessibility_phone_three_bars" msgid="1523967995996696619">"Сигнал телефона од три црте."</string>
+ <string name="accessibility_phone_signal_full" msgid="4302338883816077134">"Сигнал телефона је пун."</string>
+ <string name="accessibility_no_data" msgid="4563181886936931008">"Нема података."</string>
+ <string name="accessibility_data_one_bar" msgid="6892888138070752480">"Сигнал за податке има једну црту."</string>
+ <string name="accessibility_data_two_bars" msgid="9202641507241802499">"Сигнал за податке од две црте."</string>
+ <string name="accessibility_data_three_bars" msgid="2813876214466722413">"Сигнал за податке од три црте."</string>
+ <string name="accessibility_data_signal_full" msgid="1808301899314382337">"Сигнал за податке је најјачи."</string>
+ <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Веза са етернетом је прекинута."</string>
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Етернет."</string>
+ <string name="accessibility_no_calling" msgid="3540827068323895748">"Без позивања."</string>
+ <string name="avatar_picker_title" msgid="8492884172713170652">"Одаберите слику профила"</string>
+ <string name="default_user_icon_description" msgid="6554047177298972638">"Подразумевана икона корисника"</string>
+ <string name="physical_keyboard_title" msgid="4811935435315835220">"Физичка тастатура"</string>
+ <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Одаберите распоред тастатуре"</string>
+ <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Подразумевано"</string>
+ <string name="turn_screen_on_title" msgid="3266937298097573424">"Укључите екран"</string>
+ <string name="allow_turn_screen_on" msgid="6194845766392742639">"Дозволи укључивање екрана"</string>
+ <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Дозвољава апликацији да укључи екран. Ако се омогући, апликација може да укључи екран у било ком тренутку без ваше експлицитне намере."</string>
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Желите да зауставите емитовање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Промените излаз"</string>
+ <string name="back_navigation_animation" msgid="8105467568421689484">"Анимације за покрет повратка са предвиђањем"</string>
+ <string name="back_navigation_animation_summary" msgid="741292224121599456">"Омогућите анимације система за покрет повратка са предвиђањем."</string>
+ <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ово подешавање омогућава анимације система за покрет повратка са предвиђањем. Захтева подешавање дозволе enableOnBackInvokedCallback по апликацији на true у фајлу манифеста."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 5203e17..1fccad9 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Да поўнай зарадкі засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – да поўнай зарадкі засталося: <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Зарадка прыпынена"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарадка да <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Невядома"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Зарадка"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хуткая зарадка"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index ffe894a..5ce9cba 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Оставащо време до пълно зареждане: <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – зареждането е на пауза"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарежда се до <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Зарежда се"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Зарежда се бързо"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 3613c61..bca3eb1 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>-এ ব্যাটারি পুরো চার্জ হয়ে যাবে"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>-এ ব্যাটারি পুরো চার্জ হয়ে যাবে"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - চার্জিং পজ করা হয়েছে"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> পর্যন্ত চার্জ হচ্ছে"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"অজানা"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"চার্জ হচ্ছে"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্রুত চার্জ হচ্ছে"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 90ff2c6..b5e75e4 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Punjenje je pauzirano"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Punjenje do <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Punjenje"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index b11d251..cff34e3 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> per completar la càrrega"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g>: la càrrega s\'ha posat en pausa"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g>: s\'està carregant fins al <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconegut"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"S\'està carregant"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregant ràpidament"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index a54d5d9..f5b7600 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do úplného nabití"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Nabíjení pozastaveno"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – nabíjení do <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Neznámé"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Nabíjí se"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rychlé nabíjení"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 49bb22c..1f3d5f9 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Fuldt opladet om <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – fuldt opladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Opladning er sat på pause"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Oplader til <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Ukendt"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Oplader"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Oplader hurtigt"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 752afbc..35e8637 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Voll in <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laden pausiert"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Aufladung auf <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Unbekannt"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Wird aufgeladen"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Schnelles Aufladen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index bf43bf5..200c640 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> για πλήρη φόρτιση"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - Απομένουν <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Φόρτιση σε παύση"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Φόρτιση έως το <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Άγνωστο"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Φόρτιση"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ταχεία φόρτιση"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 859139b..000cd8a 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> left until full"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – charging paused"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – charging to <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 6711436..ae72573 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -477,8 +477,8 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left until full"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging paused"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging to <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimized"</string>
+ <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimized"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 859139b..000cd8a 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> left until full"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – charging paused"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – charging to <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 859139b..000cd8a 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> left until full"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – charging paused"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – charging to <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index d9afda1e..2e93464 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -477,8 +477,8 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left until full"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging paused"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging to <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimized"</string>
+ <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimized"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index c35dbe5..d89aff6 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> para completar"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Se pausó la carga"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Cargando hasta <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápidamente"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index ca38182..794d64f 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> hasta la carga completa"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> hasta la carga completa"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga pausada"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Cargando hasta <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carga rápida"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 4a1f6c3..4204320 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Täislaadimiseks kulub <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – täislaadimiseks kulub <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – laadimine peatati"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – laadimine tasemeni <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Tundmatu"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Laadimine"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Kiirlaadimine"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index ec492a8..92eaf2b 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kargatze-prozesua pausatuta dago"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> arte kargatzen"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Ezezaguna"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Kargatzen"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Bizkor kargatzen"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 7320b23..6bdbc0e 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> تا شارژ کامل باقی مانده است"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل باقی مانده است"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - شارژ موقتاً متوقف شد"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - درحال شارژ تا <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"ناشناس"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"در حال شارژ شدن"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"درحال شارژ شدن سریع"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 3c0194f..a6eb736 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> kunnes täynnä"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Lataaminen keskeytetty"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tavoite: <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Tuntematon"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Ladataan"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Nopea lataus"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index d4dba9d..477e2de1 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à la recharge complète"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la recharge complète)"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Recharge interrompue"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - En charge jusqu\'à <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Charge en cours…"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Recharge rapide"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index fad8e1e..fe1744e 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Chargée à 100 %% dans <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Recharge interrompue"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Recharge jusqu\'à <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Batterie en charge"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charge rapide"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 050e1dc..2f4eb5b 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> para completar a carga"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> para completar a carga)"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g>: Carga en pausa"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g>: Cargando ata o <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Descoñecido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rapidamente"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 066c7ab..267c468 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"પૂર્ણ ચાર્જ થવામાં <xliff:g id="TIME">%1$s</xliff:g> બાકી છે"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - પૂર્ણ ચાર્જ થવામાં <xliff:g id="TIME">%2$s</xliff:g> બાકી છે"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જિંગ થોભાવેલું છે"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> સુધી ચાર્જિંગ"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"અજાણ્યું"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ચાર્જ થઈ રહ્યું છે"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ઝડપથી ચાર્જ થાય છે"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index f853785..0ad754c 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> में बैटरी पूरी चार्ज हो जाएगी"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> में बैटरी पूरी चार्ज हो जाएगी"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंग रोकी गई है"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> तक चार्ज किया जा रहा है"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हो रही है"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"तेज़ चार्ज हो रही है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index f666302..34c82b1 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do napunjenosti"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje pauzirano"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje do <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Punjenje"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index ac41654..2a43d15 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> a teljes töltöttségig"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes töltöttségig"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Töltés szüneteltetve"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Töltés eddig: <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Ismeretlen"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Töltés"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Gyorstöltés"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 51b96ac..8442bf5 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Լիցքավորումը դադարեցվել է"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Լիցքավորում մինչև <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Անհայտ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Լիցքավորում"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Արագ լիցքավորում"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 2cd8321..d1e490f 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> lagi sampai penuh"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi sampai penuh"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengisian daya dijeda"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Mengisi daya sampai <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Mengisi daya"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengisi daya cepat"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 5bfb2f1..b011b2d 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> fram að fullri hleðslu"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> fram að fullri hleðslu"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Hlé gert á hleðslu"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - hleður upp að <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Óþekkt"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Í hleðslu"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hröð hleðsla"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 1386fe9..b659443 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> alla ricarica completa"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla ricarica completa"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ricarica in pausa"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ricarica fino a <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Sconosciuta"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"In carica"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ricarica veloce"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 65ff52b..7303a2d 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"הזמן הנותר לטעינה מלאה: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – הזמן הנותר לטעינה מלאה: <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – הטעינה מושהית"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – טעינה עד מצב של <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"לא ידוע"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"בטעינה"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"הסוללה נטענת מהר"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index f2892a6..1f80d48 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"完了まであと <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - 完了まであと <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電を一時停止しています"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> まで充電"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"不明"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"急速充電中"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index df420dc..fd37a860 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> — სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - დატენვა დაპაუზებულია"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – დატენვა შემდეგ ნიშნულამდე: <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"უცნობი"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"იტენება"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"სწრაფად იტენება"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 45bd897..dea3570 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Толық зарядталғанға дейін <xliff:g id="TIME">%1$s</xliff:g> қалды."</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g> қалды."</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зарядтау кідіртілді"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> деңгейіне дейін зарядталады"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Белгісіз"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Зарядталуда"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Жылдам зарядталуда"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 83f041f..4ed0952 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបពេញ"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបពេញ"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - បានផ្អាកការសាកថ្ម"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - កំពុងសាកថ្មឱ្យដល់កម្រិត <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"មិនស្គាល់"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"កំពុងសាកថ្ម"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"កំពុងសាកថ្មយ៉ាងឆាប់រហ័ស"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 541f958..e18a3f1 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> - ಸಮಯದಲ್ಲಿ ಪೂರ್ತಿ ಚಾರ್ಜ್ ಆಗುತ್ತದೆ"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯದಲ್ಲಿ ಪೂರ್ತಿ ಚಾರ್ಜ್ ಆಗುತ್ತದೆ"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜಿಂಗ್ ವಿರಾಮಗೊಂಡಿದೆ"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> ವರೆಗೆ ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"ಅಪರಿಚಿತ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ವೇಗದ ಚಾರ್ಜಿಂಗ್"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index d79ea18..42ec09c 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> 후 충전 완료"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 일시중지됨"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>까지 충전"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"알 수 없음"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"충전 중"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"고속 충전 중"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index efdaf81d..1e3453b 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> кийин толук кубатталат"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Кубаттоо тындырылды"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> чейин кубаттоо"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Белгисиз"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Кубатталууда"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ыкчам кубатталууда"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index d08ee27..63ff4df 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ຍັງເຫຼືອອີກ <xliff:g id="TIME">%1$s</xliff:g> ຈຶ່ງຈະສາກເຕັມ"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"ຍັງເຫຼືອອີກ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະສາກເຕັມ"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຢຸດການສາກໄວ້ຊົ່ວຄາວແລ້ວ"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - ກຳລັງສາກຈົນເຖິງ <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"ບໍ່ຮູ້ຈັກ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ກຳລັງສາກໄຟ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ກຳລັງສາກໄຟດ່ວນ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 2516d5b..765fb10 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Liko <xliff:g id="TIME">%1$s</xliff:g>, kol bus visiškai įkrauta"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko <xliff:g id="TIME">%2$s</xliff:g>, kol bus visiškai įkrauta"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – įkrovimas pristabdytas"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – įkraunama iki <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nežinomas"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Kraunasi..."</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Greitai įkraunama"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index cac21e1..222e41a 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> līdz pilnai uzlādei"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Uzlāde ir apturēta"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g>. Tiks uzlādēts līdz <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nezināms"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Uzlāde"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Notiek ātrā uzlāde"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index c83c23b..f672c60 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до полна батерија"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> до полна батерија"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Полнењето е паузирано"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Се полни на <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Се полни"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо полнење"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 2b85ed5..e6ccc5a 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"പൂർണ്ണമാകാൻ <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമാകാൻ <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - ചാർജ് ചെയ്യൽ താൽക്കാലികമായി നിർത്തി"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> വരെ ചാർജ് ചെയ്യുന്നു"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"അജ്ഞാതം"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ചാർജ് ചെയ്യുന്നു"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"അതിവേഗ ചാർജിംഗ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index a84410a..71630d4 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Дүүрэх хүртэл <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - дүүрэх хүртэл <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Цэнэглэлтийг түр зогсоосон"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> руу цэнэглэж байна"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Тодорхойгүй"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Цэнэглэж байна"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хурдан цэнэглэж байна"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 9c04534..0493ffe 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"पूर्ण चार्ज होण्यासाठी <xliff:g id="TIME">%1$s</xliff:g> शिल्लक आहेत"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्ण चार्ज होण्यासाठी <xliff:g id="TIME">%2$s</xliff:g> शिल्लक आहे"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्ज करणे थांबवले"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> वर चार्ज करत आहे"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज होत आहे"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"वेगाने चार्ज होत आहे"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 9a6eaf6..bb3b65b 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> lagi sebelum penuh"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi sebelum penuh"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengecasan dijeda"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Mengecas kepada <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Mengecas"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengecas dgn cepat"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 6346b11..5bcaa27 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> လိုသည်"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"အားပြည့်ရန် <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> လိုသည်"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းမှု ခဏရပ်ထားသည်"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> အထိ အားသွင်းရန်"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"မသိ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"အားသွင်းနေပါသည်"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"အမြန် အားသွင်းနေသည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index a4431ab..e42e939 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Fulladet om <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Fulladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ladingen er satt på pause"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – lader til <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Ukjent"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Lader"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Lader raskt"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index bab48c2..8c5171b 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"पूरा चार्ज हुन <xliff:g id="TIME">%1$s</xliff:g> लाग्ने छ"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूरा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> लाग्ने छ"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्ज गर्ने प्रक्रिया पज गरिएको छ"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> सम्म चार्ज हुने छ"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हुँदै छ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"द्रुत गतिमा चार्ज गरिँदै छ"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 8ad3a734..aa70f9b 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Vol over <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - vol over <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Opladen onderbroken"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Opladen tot <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Opladen"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Snel opladen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 0109527..a39e0ec 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ପୂର୍ଣ୍ଣ ହେବାକୁ ଆଉ <xliff:g id="TIME">%1$s</xliff:g> ବାକି ଅଛି"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - ପୂର୍ଣ୍ଣ ହେବାକୁ ଆଉ <xliff:g id="TIME">%2$s</xliff:g> ବାକି ଅଛି"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - ଚାର୍ଜିଂ ବିରତ କରାଯାଇଛି"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> ପର୍ଯ୍ୟନ୍ତ ଚାର୍ଜ ହେଉଛି"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"ଅଜ୍ଞାତ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ଚାର୍ଜ ହେଉଛି"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ଶୀଘ୍ର ଚାର୍ଜ ହେଉଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 1c95605..4a729c9 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ਬੈਟਰੀ ਪੂਰੀ ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਬੈਟਰੀ ਪੂਰੀ ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਬੈਟਰੀ ਦੀ ਚਾਰਜਿੰਗ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> ਤੱਕ ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"ਅਗਿਆਤ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ਤੇਜ਼ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 4b1c734..935ac2d 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do pełnego naładowania"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – wstrzymano ładowanie"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ładuję do <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nieznane"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Ładowanie"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Szybkie ładowanie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index e704049..0ada85c 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> até a conclusão"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> até a conclusão"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g>: carregamento pausado"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g>: carregando até <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Carregando"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregando rápido"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 4a75c0b..fca397d 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> até à carga máxima"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até à carga máxima"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Carregamento em pausa"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – A carregar até <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"A carregar"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregamento rápido"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index e704049..0ada85c 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> até a conclusão"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> até a conclusão"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g>: carregamento pausado"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g>: carregando até <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Carregando"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregando rápido"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 90c08c3..0ce8f46 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> până la finalizare"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> până la finalizare"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Încărcarea s-a întrerupt"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Se încarcă până la <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Necunoscut"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Se încarcă"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Se încarcă rapid"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index b74363f..ac97cb8 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до полной зарядки"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядка приостановлена"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – заряжается до <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Идет зарядка"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Быстрая зарядка"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index b2251ed..099202c 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"සම්පූර්ණ වීමට <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතිරියි"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - සම්පූර්ණ වීමට <xliff:g id="TIME">%2$s</xliff:g>ක් ඉතිරියි"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආරෝපණය විරාම කළා"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> වෙත ආරෝපණය"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"නොදනී"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ආරෝපණය වෙමින්"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ශීඝ්ර ආරෝපණය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index baeccad..06e822e 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do úplného nabitia"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – nabíjanie bolo pozastavené"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – nabíja sa na úroveň <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Neznáme"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Nabíja sa"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rýchle nabíjanie"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index ec818b3..4e4d540 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Še <xliff:g id="TIME">%1$s</xliff:g> do napolnjenosti"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – še <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – polnjenje je začasno zaustavljeno"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – polnjenje do <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Neznano"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Polnjenje"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hitro polnjenje"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 74e8124..86aaf6a 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> derisa të mbushet"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Karikimi në pauzë"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Po karikohet deri në <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"I panjohur"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Po karikohet"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Karikim i shpejtë"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 4c7a9670..68af019 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до краја пуњења"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до краја пуњења"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Пуњење је паузирано"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – пуњење до <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Пуни се"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо се пуни"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 726bf5e..0b2939e 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> kvar tills fulladdat"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kvar tills fulladdat"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laddningen har pausats"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laddar till <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Okänd"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Laddar"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laddas snabbt"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index f287e42..49486670 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g> ijae chaji"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> zimesalia ijae chaji"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Imesitisha kuchaji"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Itachaji hadi <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Haijulikani"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Inachaji"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Inachaji kwa kasi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index a96a3ce..9b22973 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"முழுவதும் சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g> ஆகும்"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - முழுவதும் சார்ஜாக <xliff:g id="TIME">%2$s</xliff:g> ஆகும்"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - சார்ஜிங் இடைநிறுத்தப்பட்டது"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> வரை சார்ஜ் செய்யப்படும்"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"அறியப்படாத"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"சார்ஜ் ஆகிறது"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"வேகமாக சார்ஜாகிறது"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index ca2f143..311d3c9 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -342,7 +342,7 @@
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"బ్లూటూత్ Gabeldorsche ఫీచర్ స్ట్యాక్ను ఎనేబుల్ చేస్తుంది."</string>
<string name="enhanced_connectivity_summary" msgid="1576414159820676330">"మెరుగైన కనెక్టివిటీ ఫీచర్ను ఎనేబుల్ చేస్తుంది."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"స్థానిక టెర్మినల్"</string>
- <string name="enable_terminal_summary" msgid="2481074834856064500">"స్థానిక షెల్ యాక్సెస్ను అందించే టెర్మినల్ యాప్ను ప్రారంభించు"</string>
+ <string name="enable_terminal_summary" msgid="2481074834856064500">"స్థానిక షెల్ యాక్సెస్ను అందించే టెర్మినల్ యాప్ను ప్రారంభించండి"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP చెకింగ్"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP తనిఖీ ప్రవర్తనను సెట్ చేయండి"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"డీబగ్గింగ్"</string>
@@ -396,7 +396,7 @@
<string name="overlay_display_devices_title" msgid="5411894622334469607">"ఇతర డిస్ప్లేలను సిమ్యులేట్ చేయండి"</string>
<string name="debug_applications_category" msgid="5394089406638954196">"యాప్లు"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"యాక్టివిటీస్ను ఉంచవద్దు"</string>
- <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"యూజర్ నిష్క్రమించాక పూర్తి యాక్టివిటీని తొలగించు"</string>
+ <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"యూజర్ నిష్క్రమించాక పూర్తి యాక్టివిటీని తొలగించండి"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"బ్యాక్గ్రౌండ్ ప్రాసెస్ పరిమితి"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"బ్యాక్గ్రౌండ్ ANRలను చూపు"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"బ్యాక్గ్రౌండ్ యాప్ల కోసం యాప్ ప్రతిస్పందించడం లేదు అనే డైలాగ్ను చూపు"</string>
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - ఛార్జింగ్ పాజ్ చేయబడింది"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> ఛార్జింగ్"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"తెలియదు"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ఛార్జ్ అవుతోంది"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"వేగవంతమైన ఛార్జింగ్"</string>
@@ -565,7 +567,7 @@
<string name="accessor_info_title" msgid="8289823651512477787">"యాప్ల షేరింగ్ డేటా"</string>
<string name="accessor_no_description_text" msgid="7510967452505591456">"యాప్ ద్వారా ఎలాంటి వివరణ అందించబడలేదు."</string>
<string name="accessor_expires_text" msgid="4625619273236786252">"లీజు గడువు <xliff:g id="DATE">%s</xliff:g>తో ముగుస్తుంది"</string>
- <string name="delete_blob_text" msgid="2819192607255625697">"షేర్ చేసిన డేటాను తొలగించు"</string>
+ <string name="delete_blob_text" msgid="2819192607255625697">"షేర్ చేసిన డేటాను తొలగించండి"</string>
<string name="delete_blob_confirmation_text" msgid="7807446938920827280">"మీరు ఖచ్చితంగా ఈ షేర్ చేసిన డేటాను తొలగించాలనుకుంటున్నారా?"</string>
<string name="user_add_user_item_summary" msgid="5748424612724703400">"వినియోగదారులు వారి స్వంత యాప్లను మరియు కంటెంట్ను కలిగి ఉన్నారు"</string>
<string name="user_add_profile_item_summary" msgid="5418602404308968028">"మీరు మీ ఖాతా నుండి యాప్లకు మరియు కంటెంట్కు యాక్సెస్ను పరిమితం చేయవచ్చు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 2388d70..680e7d6 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"อีก <xliff:g id="TIME">%1$s</xliff:g>จึงจะเต็ม"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - อีก <xliff:g id="TIME">%2$s</xliff:g> จึงจะเต็ม"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - หยุดชาร์จชั่วคราว"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - กำลังชาร์จจนถึง <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"ไม่ทราบ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"กำลังชาร์จ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"กำลังชาร์จอย่างเร็ว"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 8f0a4ef..f4bf11d9 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> na lang bago mapuno"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> na lang bago mapuno"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Na-pause ang pag-charge"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - China-charge hanggang <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Hindi Kilala"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Nagcha-charge"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mabilis na charge"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 4d1dc8d..74762a6 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Tamamen şarj olmasına <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tamamen şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj işlemi duraklatıldı"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> seviyesine kadar şarj ediliyor"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Bilinmiyor"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Şarj oluyor"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hızlı şarj oluyor"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 3497b25..19b2496 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до повного заряду"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – заряджання призупинено"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Заряджання до <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Невідомо"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Заряджається"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Швидке заряджання"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 31c0671..112217d 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"مکمل چارج ہونے میں <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"مکمل چارج ہونے میں <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - چارجنگ موقوف کی گئی"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> چارج کیا جائے گا"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"نامعلوم"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"چارج ہو رہا ہے"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"تیزی سے چارج ہو رہا ہے"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 48aa194..6ce7053 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Toʻlishiga <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Toʻlishiga <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Quvvatlash pauzada"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g>, <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g> gacha quvvat oladi"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Noma’lum"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Quvvat olmoqda"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Tezkor quvvat olmoqda"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index aa4eb69..b9121ab 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> nữa là pin đầy"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> nữa là pin đầy"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> – Đã tạm dừng sạc"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> – Sạc đến <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Không xác định"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Đang sạc"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Đang sạc nhanh"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index c24bd99..d59aba1 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"还需<xliff:g id="TIME">%1$s</xliff:g>充满"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - 已暂停充电"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - 正在充到 <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"正在充电"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"正在快速充电"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 6cd192c..fd607226 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>後充滿電"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充滿電"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - 已暫停充電"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - 正在充電至 <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 0195184..3ae32b4 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>後充飽"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - 已暫停充電"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - 正在充電至 <xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"不明"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 0bed056..57de713 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -477,8 +477,10 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> okusele kuze kugcwale"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> okusele kuze kugcwale"</string>
- <string name="power_charging_limited" msgid="6732738149313642521">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ukushaja kumiswe isikhashana"</string>
- <string name="power_charging_future_paused" msgid="6829683663982987290">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ishaja ku-<xliff:g id="DOCK_DEFENDER_THRESHOLD">%2$s</xliff:g>"</string>
+ <!-- no translation found for power_charging_limited (8202147604844938236) -->
+ <skip />
+ <!-- no translation found for power_charging_future_paused (4730177778538118032) -->
+ <skip />
<string name="battery_info_status_unknown" msgid="268625384868401114">"Akwaziwa"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Iyashaja"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ishaja ngokushesha"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index d1ac7d0..cf37205 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1125,9 +1125,9 @@
<!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
<string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> left until full</string>
<!-- [CHAR_LIMIT=80] Label for battery level chart when charge been limited -->
- <string name="power_charging_limited"><xliff:g id="level">%1$s</xliff:g> - Charging paused</string>
+ <string name="power_charging_limited"><xliff:g id="level">%1$s</xliff:g> - Charging optimized</string>
<!-- [CHAR_LIMIT=80] Label for battery charging future pause -->
- <string name="power_charging_future_paused"><xliff:g id="level">%1$s</xliff:g> - Charging to <xliff:g id="dock_defender_threshold">%2$s</xliff:g></string>
+ <string name="power_charging_future_paused"><xliff:g id="level">%1$s</xliff:g> - Charging optimized</string>
<!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
<string name="battery_info_status_unknown">Unknown</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index a822e18..5611976 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -308,8 +308,16 @@
@ColorInt
public static int getColorAttrDefaultColor(Context context, int attr) {
+ return getColorAttrDefaultColor(context, attr, 0);
+ }
+
+ /**
+ * Get color styled attribute {@code attr}, default to {@code defValue} if not found.
+ */
+ @ColorInt
+ public static int getColorAttrDefaultColor(Context context, int attr, @ColorInt int defValue) {
TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
- @ColorInt int colorAccent = ta.getColor(0, 0);
+ @ColorInt int colorAccent = ta.getColor(0, defValue);
ta.recycle();
return colorAccent;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index a9f4e9c..4d6dd4b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -233,7 +233,22 @@
@Nullable CachedBluetoothDevice activeDevice,
int bluetoothProfile) {
for (CachedBluetoothDevice cachedDevice : mDeviceManager.getCachedDevicesCopy()) {
+ Set<CachedBluetoothDevice> memberSet = cachedDevice.getMemberDevice();
boolean isActive = Objects.equals(cachedDevice, activeDevice);
+ if (!isActive && !memberSet.isEmpty()) {
+ for (CachedBluetoothDevice memberCachedDevice : memberSet) {
+ isActive = Objects.equals(memberCachedDevice, activeDevice);
+ if (isActive) {
+ Log.d(TAG,
+ "The active device is the member device "
+ + activeDevice.getDevice().getAnonymizedAddress()
+ + ". change activeDevice as main device "
+ + cachedDevice.getDevice().getAnonymizedAddress());
+ activeDevice = cachedDevice;
+ break;
+ }
+ }
+ }
cachedDevice.onActiveDeviceChanged(isActive, bluetoothProfile);
}
for (BluetoothCallback callback : mCallbacks) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java b/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java
index c941954..840c936 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java
@@ -251,5 +251,22 @@
}
return config;
}
+
+ /**
+ * Returns true if this config and the other config are semantically equal.
+ *
+ * Does not override isEquals because existing clients may be relying on the currently
+ * defined equals behavior.
+ */
+ public boolean areEqual(Config other) {
+ return showAtLeast3G == other.showAtLeast3G
+ && show4gFor3g == other.show4gFor3g
+ && alwaysShowCdmaRssi == other.alwaysShowCdmaRssi
+ && show4gForLte == other.show4gForLte
+ && show4glteForLte == other.show4glteForLte
+ && hideLtePlus == other.hideLtePlus
+ && hspaDataDistinguishable == other.hspaDataDistinguishable
+ && alwaysShowDataRatIcon == other.alwaysShowDataRatIcon;
+ }
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
index 7b94492..3361a66 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
@@ -70,10 +70,14 @@
@Mock
private HearingAidProfile mHearingAidProfile;
@Mock
+ private LeAudioProfile mLeAudioProfile;
+ @Mock
private BluetoothDevice mDevice1;
@Mock
private BluetoothDevice mDevice2;
@Mock
+ private BluetoothDevice mDevice3;
+ @Mock
private LocalBluetoothProfileManager mLocalProfileManager;
@Mock
private BluetoothUtils.ErrorListener mErrorListener;
@@ -83,6 +87,7 @@
private BluetoothEventManager mBluetoothEventManager;
private CachedBluetoothDevice mCachedDevice1;
private CachedBluetoothDevice mCachedDevice2;
+ private CachedBluetoothDevice mCachedDevice3;
@Before
public void setUp() {
@@ -95,9 +100,10 @@
when(mHfpProfile.isProfileReady()).thenReturn(true);
when(mA2dpProfile.isProfileReady()).thenReturn(true);
when(mHearingAidProfile.isProfileReady()).thenReturn(true);
-
+ when(mLeAudioProfile.isProfileReady()).thenReturn(true);
mCachedDevice1 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1);
mCachedDevice2 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2);
+ mCachedDevice3 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice3);
BluetoothUtils.setErrorListener(mErrorListener);
}
@@ -293,6 +299,43 @@
assertThat(mCachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
}
+ @Test
+ public void dispatchActiveDeviceChanged_connectedMemberDevices_activeDeviceChanged() {
+ final List<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+ cachedDevices.add(mCachedDevice1);
+ cachedDevices.add(mCachedDevice2);
+
+ int group1 = 1;
+ when(mDevice3.getAddress()).thenReturn("testAddress3");
+ mCachedDevice1.setGroupId(group1);
+ mCachedDevice3.setGroupId(group1);
+ mCachedDevice1.addMemberDevice(mCachedDevice3);
+
+ when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mDevice3.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+
+ // Connect device1 and device3 for LE and device2 for A2DP and HFP
+ mCachedDevice1.onProfileStateChanged(mLeAudioProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice3.onProfileStateChanged(mLeAudioProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice2.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice2.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+
+ // Verify that both devices are connected and none is Active
+ assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).isFalse();
+ assertThat(mCachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+ assertThat(mCachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
+ assertThat(mCachedDevice3.isActiveDevice(BluetoothProfile.LE_AUDIO)).isFalse();
+
+ // The member device is active.
+ mBluetoothEventManager.dispatchActiveDeviceChanged(mCachedDevice3,
+ BluetoothProfile.LE_AUDIO);
+
+ // The main device is active since the member is active.
+ assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).isTrue();
+ }
+
/**
* Test to verify onActiveDeviceChanged() with A2DP and Hearing Aid.
*/
diff --git a/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml b/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml
index def4b68..4d05762 100644
--- a/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4567566098528588863">"Podešavanja skladišta"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Podešavanja hotspota su promenjena"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Dodirnite da biste videli detalje"</string>
+ <string name="app_label" msgid="4567566098528588863">"Подешавања складишта"</string>
+ <string name="wifi_softap_config_change" msgid="5688373762357941645">"Подешавања хотспота су промењена"</string>
+ <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Додирните да бисте видели детаље"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 46a94fd..99b15db 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -165,6 +165,9 @@
<!-- Default for Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS -->
<bool name="def_lock_screen_allow_private_notifications">true</bool>
+ <!-- Default for Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS -->
+ <bool name="def_lock_screen_show_only_unseen_notifications">false</bool>
+
<!-- Default for Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, 1==on -->
<integer name="def_heads_up_enabled">1</integer>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 92a938c..1b0b6b4 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -146,6 +146,7 @@
Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
+ Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
Settings.Secure.SHOW_NOTIFICATION_SNOOZE,
Settings.Secure.NOTIFICATION_HISTORY_ENABLED,
Settings.Secure.ZEN_DURATION,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index eabf4cc..4fa490f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -219,6 +219,7 @@
VALIDATORS.put(Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SHOW_NOTIFICATION_SNOOZE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.NOTIFICATION_HISTORY_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ZEN_DURATION, ANY_INTEGER_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index ded7e785..84a5593 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -3631,7 +3631,7 @@
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 211;
+ private static final int SETTINGS_VERSION = 212;
private final int mUserId;
@@ -5527,6 +5527,26 @@
}
currentVersion = 211;
}
+ if (currentVersion == 211) {
+ // Version 211: Set default value for
+ // Secure#LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS
+ final SettingsState secureSettings = getSecureSettingsLocked(userId);
+ final Setting lockScreenUnseenSetting = secureSettings
+ .getSettingLocked(Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS);
+ if (lockScreenUnseenSetting.isNull()) {
+ final boolean defSetting = getContext().getResources()
+ .getBoolean(R.bool.def_lock_screen_show_only_unseen_notifications);
+ secureSettings.insertSettingOverrideableByRestoreLocked(
+ Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
+ defSetting ? "1" : "0",
+ null /* tag */,
+ true /* makeDefault */,
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
+ currentVersion = 212;
+ }
+
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {
diff --git a/packages/Shell/res/values-b+sr+Latn/strings.xml b/packages/Shell/res/values-b+sr+Latn/strings.xml
index 805aed6..3513afc 100644
--- a/packages/Shell/res/values-b+sr+Latn/strings.xml
+++ b/packages/Shell/res/values-b+sr+Latn/strings.xml
@@ -17,31 +17,31 @@
<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="3701846017049540910">"Shell"</string>
- <string name="bugreport_notification_channel" msgid="2574150205913861141">"Izveštaji o greškama"</string>
- <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Izveštaj o grešci <xliff:g id="ID">#%d</xliff:g> se generiše"</string>
- <string name="bugreport_finished_title" msgid="4429132808670114081">"Izveštaj o grešci <xliff:g id="ID">#%d</xliff:g> je snimljen"</string>
- <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodaju se detalji u izveštaj o grešci"</string>
- <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sačekajte..."</string>
- <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Izveštaj o grešci će se uskoro pojaviti na telefonu"</string>
- <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Izaberite da biste delili izveštaj o grešci"</string>
- <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste delili izveštaj o grešci"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Izaberite da biste delili izveštaj o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
- <string name="bugreport_confirm" msgid="5917407234515812495">"Izveštaji o greškama sadrže podatke iz različitih sistemskih datoteka evidencije, koji obuhvataju lične i privatne podatke (poput korišćenja aplikacija i podataka o lokaciji). Delite izveštaje o greškama samo sa aplikacijama i ljudima u koje imate poverenja."</string>
- <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ne prikazuj ponovo"</string>
- <string name="bugreport_storage_title" msgid="5332488144740527109">"Izveštaji o greškama"</string>
- <string name="bugreport_unreadable_text" msgid="586517851044535486">"Datoteka izveštaja o grešci ne može da se pročita"</string>
- <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Dodavanje detalja izveštaja o grešci u zip datoteku nije uspelo"</string>
- <string name="bugreport_unnamed" msgid="2800582406842092709">"neimenovano"</string>
- <string name="bugreport_info_action" msgid="2158204228510576227">"Detalji"</string>
- <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Snimci ekrana"</string>
- <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Snimak ekrana je napravljen."</string>
- <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snimanje ekrana nije uspelo."</string>
- <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalji izveštaja o grešci <xliff:g id="ID">#%d</xliff:g>"</string>
- <string name="bugreport_info_name" msgid="4414036021935139527">"Naziv datoteke"</string>
- <string name="bugreport_info_title" msgid="2306030793918239804">"Naslov greške"</string>
- <string name="bugreport_info_description" msgid="5072835127481627722">"Rezime greške"</string>
- <string name="save" msgid="4781509040564835759">"Sačuvaj"</string>
- <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Deli izveštaj o grešci"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"Извештаји о грешкама"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Извештај о грешци <xliff:g id="ID">#%d</xliff:g> се генерише"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"Извештај о грешци <xliff:g id="ID">#%d</xliff:g> је снимљен"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"Додају се детаљи у извештај о грешци"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"Сачекајте..."</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Извештај о грешци ће се ускоро појавити на телефону"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Изаберите да бисте делили извештај о грешци"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Додирните да бисте делили извештај о грешци"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Изаберите да бисте делили извештај о грешци без снимка екрана или сачекајте да се направи снимак екрана"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Додирните за дељење извештаја о грешци без снимка екрана или сачекајте да се направи снимак екрана"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Додирните за дељење извештаја о грешци без снимка екрана или сачекајте да се направи снимак екрана"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"Извештаји о грешкама садрже податке из различитих системских датотека евиденције, који обухватају личне и приватне податке (попут коришћења апликацијa и података о локацији). Делите извештаје о грешкама само са апликацијама и људима у које имате поверења."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Не приказуј поново"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"Извештаји о грешкама"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"Датотека извештаја о грешци не може да се прочита"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Додавање детаља извештаја о грешци у zip датотеку није успело"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"неименовано"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"Детаљи"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Снимци екрана"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Снимак екрана је направљен."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Снимање екрана није успело."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Детаљи извештаја о грешци <xliff:g id="ID">#%d</xliff:g>"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"Назив датотеке"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"Наслов грешке"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"Резиме грешке"</string>
+ <string name="save" msgid="4781509040564835759">"Сачувај"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Дели извештај о грешци"</string>
</resources>
diff --git a/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml b/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml
index f7771c5..5d5921e4 100644
--- a/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml
+++ b/packages/SimAppDialog/res/values-b+sr+Latn/strings.xml
@@ -18,9 +18,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string>
- <string name="install_carrier_app_title" msgid="334729104862562585">"Aktivirajte mobilnu uslugu"</string>
- <string name="install_carrier_app_description" msgid="4014303558674923797">"Da bi nova SIM kartica ispravno radila, treba da instalirate aplikaciju <xliff:g id="ID_1">%1$s</xliff:g>"</string>
- <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Da bi nova SIM kartica ispravno radila, treba da instalirate aplikaciju mobilnog operatera"</string>
- <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Ne sada"</string>
- <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Preuzmi aplikaciju"</string>
+ <string name="install_carrier_app_title" msgid="334729104862562585">"Активирајте мобилну услугу"</string>
+ <string name="install_carrier_app_description" msgid="4014303558674923797">"Да би нова SIM картица исправно радила, треба да инсталирате апликацију <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Да би нова SIM картица исправно радила, треба да инсталирате апликацију мобилног оператера"</string>
+ <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Не сада"</string>
+ <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Преузми апликацију"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-b+sr+Latn/strings.xml b/packages/SoundPicker/res/values-b+sr+Latn/strings.xml
index 947c85c..bc573f5 100644
--- a/packages/SoundPicker/res/values-b+sr+Latn/strings.xml
+++ b/packages/SoundPicker/res/values-b+sr+Latn/strings.xml
@@ -16,14 +16,14 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="ringtone_default" msgid="798836092118824500">"Podrazumevani zvuk zvona"</string>
- <string name="notification_sound_default" msgid="8133121186242636840">"Podrazumevani zvuk obaveštenja"</string>
- <string name="alarm_sound_default" msgid="4787646764557462649">"Podrazumevani zvuk alarma"</string>
- <string name="add_ringtone_text" msgid="6642389991738337529">"Dodaj melodiju zvona"</string>
- <string name="add_alarm_text" msgid="3545497316166999225">"Dodajte alarm"</string>
- <string name="add_notification_text" msgid="4431129543300614788">"Dodajte obaveštenje"</string>
- <string name="delete_ringtone_text" msgid="201443984070732499">"Izbriši"</string>
- <string name="unable_to_add_ringtone" msgid="4583511263449467326">"Dodavanje prilagođene melodije zvona nije uspelo"</string>
- <string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Brisanje prilagođene melodije zvona nije uspelo"</string>
- <string name="app_label" msgid="3091611356093417332">"Zvukovi"</string>
+ <string name="ringtone_default" msgid="798836092118824500">"Подразумевани звук звона"</string>
+ <string name="notification_sound_default" msgid="8133121186242636840">"Подразумевани звук обавештења"</string>
+ <string name="alarm_sound_default" msgid="4787646764557462649">"Подразумевани звук аларма"</string>
+ <string name="add_ringtone_text" msgid="6642389991738337529">"Додај мелодију звона"</string>
+ <string name="add_alarm_text" msgid="3545497316166999225">"Додајте аларм"</string>
+ <string name="add_notification_text" msgid="4431129543300614788">"Додајте обавештење"</string>
+ <string name="delete_ringtone_text" msgid="201443984070732499">"Избриши"</string>
+ <string name="unable_to_add_ringtone" msgid="4583511263449467326">"Додавање прилагођене мелодије звона није успело"</string>
+ <string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Брисање прилагођене мелодије звона није успело"</string>
+ <string name="app_label" msgid="3091611356093417332">"Звукови"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-te/strings.xml b/packages/SoundPicker/res/values-te/strings.xml
index feaf4c8..2d03ac0 100644
--- a/packages/SoundPicker/res/values-te/strings.xml
+++ b/packages/SoundPicker/res/values-te/strings.xml
@@ -19,9 +19,9 @@
<string name="ringtone_default" msgid="798836092118824500">"ఆటోమేటిక్ రింగ్టోన్"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"నోటిఫికేషన్ ఆటోమేటిక్ సౌండ్"</string>
<string name="alarm_sound_default" msgid="4787646764557462649">"అలారం ఆటోమేటిక్ సౌండ్"</string>
- <string name="add_ringtone_text" msgid="6642389991738337529">"రింగ్టోన్ను జోడించు"</string>
- <string name="add_alarm_text" msgid="3545497316166999225">"అలారాన్ని జోడించు"</string>
- <string name="add_notification_text" msgid="4431129543300614788">"నోటిఫికేషన్ని జోడించు"</string>
+ <string name="add_ringtone_text" msgid="6642389991738337529">"రింగ్టోన్ను జోడించండి"</string>
+ <string name="add_alarm_text" msgid="3545497316166999225">"అలారాన్ని జోడించండి"</string>
+ <string name="add_notification_text" msgid="4431129543300614788">"నోటిఫికేషన్ని జోడించండి"</string>
<string name="delete_ringtone_text" msgid="201443984070732499">"తొలగించండి"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"అనుకూల రింగ్టోన్ను జోడించలేకపోయింది"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"అనుకూల రింగ్టోన్ను తొలగించలేకపోయింది"</string>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index e624441..25fb24a 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -221,6 +221,7 @@
"WindowManager-Shell",
"LowLightDreamLib",
"motion_tool_lib",
+ "androidx.core_core-animation-testing-nodeps",
],
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 4f08a30..2f5b42f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -886,7 +886,7 @@
android:showForAllUsers="true"
android:finishOnTaskLaunch="true"
android:launchMode="singleInstance"
- android:configChanges="screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
android:visibleToInstantApps="true">
</activity>
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index ebabdf57..fe349f2 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -49,12 +49,12 @@
*/
class ActivityLaunchAnimator(
/** The animator used when animating a View into an app. */
- private val launchAnimator: LaunchAnimator = LaunchAnimator(TIMINGS, INTERPOLATORS),
+ private val launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR,
/** The animator used when animating a Dialog into an app. */
// TODO(b/218989950): Remove this animator and instead set the duration of the dim fade out to
// TIMINGS.contentBeforeFadeOutDuration.
- private val dialogToAppAnimator: LaunchAnimator = LaunchAnimator(DIALOG_TIMINGS, INTERPOLATORS)
+ private val dialogToAppAnimator: LaunchAnimator = DEFAULT_DIALOG_TO_APP_ANIMATOR
) {
companion object {
/** The timings when animating a View into an app. */
@@ -85,6 +85,9 @@
contentAfterFadeInInterpolator = PathInterpolator(0f, 0f, 0.6f, 1f)
)
+ private val DEFAULT_LAUNCH_ANIMATOR = LaunchAnimator(TIMINGS, INTERPOLATORS)
+ private val DEFAULT_DIALOG_TO_APP_ANIMATOR = LaunchAnimator(DIALOG_TIMINGS, INTERPOLATORS)
+
/** Durations & interpolators for the navigation bar fading in & out. */
private const val ANIMATION_DURATION_NAV_FADE_IN = 266L
private const val ANIMATION_DURATION_NAV_FADE_OUT = 133L
@@ -117,6 +120,22 @@
/** The set of [Listener] that should be notified of any animation started by this animator. */
private val listeners = LinkedHashSet<Listener>()
+ /** Top-level listener that can be used to notify all registered [listeners]. */
+ private val lifecycleListener =
+ object : Listener {
+ override fun onLaunchAnimationStart() {
+ listeners.forEach { it.onLaunchAnimationStart() }
+ }
+
+ override fun onLaunchAnimationEnd() {
+ listeners.forEach { it.onLaunchAnimationEnd() }
+ }
+
+ override fun onLaunchAnimationProgress(linearProgress: Float) {
+ listeners.forEach { it.onLaunchAnimationProgress(linearProgress) }
+ }
+ }
+
/**
* Start an intent and animate the opening window. The intent will be started by running
* [intentStarter], which should use the provided [RemoteAnimationAdapter] and return the launch
@@ -156,7 +175,7 @@
?: throw IllegalStateException(
"ActivityLaunchAnimator.callback must be set before using this animator"
)
- val runner = Runner(controller)
+ val runner = createRunner(controller)
val hideKeyguardWithAnimation = callback.isOnKeyguard() && !showOverLockscreen
// Pass the RemoteAnimationAdapter to the intent starter only if we are not hiding the
@@ -256,7 +275,18 @@
}
/** Create a new animation [Runner] controlled by [controller]. */
- @VisibleForTesting fun createRunner(controller: Controller): Runner = Runner(controller)
+ @VisibleForTesting
+ fun createRunner(controller: Controller): Runner {
+ // Make sure we use the modified timings when animating a dialog into an app.
+ val launchAnimator =
+ if (controller.isDialogLaunch) {
+ dialogToAppAnimator
+ } else {
+ launchAnimator
+ }
+
+ return Runner(controller, callback!!, launchAnimator, lifecycleListener)
+ }
interface PendingIntentStarter {
/**
@@ -353,14 +383,20 @@
* this if the animation was already started, i.e. if [onLaunchAnimationStart] was called
* before the cancellation.
*
- * If this launch animation affected the occlusion state of the keyguard, WM will provide
- * us with [newKeyguardOccludedState] so that we can set the occluded state appropriately.
+ * If this launch animation affected the occlusion state of the keyguard, WM will provide us
+ * with [newKeyguardOccludedState] so that we can set the occluded state appropriately.
*/
fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {}
}
- @VisibleForTesting
- inner class Runner(private val controller: Controller) : IRemoteAnimationRunner.Stub() {
+ class Runner(
+ private val controller: Controller,
+ private val callback: Callback,
+ /** The animator to use to animate the window launch. */
+ private val launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR,
+ /** Listener for animation lifecycle events. */
+ private val listener: Listener? = null
+ ) : IRemoteAnimationRunner.Stub() {
private val launchContainer = controller.launchContainer
private val context = launchContainer.context
private val transactionApplierView =
@@ -448,18 +484,9 @@
left = windowBounds.left,
right = windowBounds.right
)
- val callback = this@ActivityLaunchAnimator.callback!!
val windowBackgroundColor =
window.taskInfo?.let { callback.getBackgroundColor(it) } ?: window.backgroundColor
- // Make sure we use the modified timings when animating a dialog into an app.
- val launchAnimator =
- if (controller.isDialogLaunch) {
- dialogToAppAnimator
- } else {
- launchAnimator
- }
-
// TODO(b/184121838): We should somehow get the top and bottom radius of the window
// instead of recomputing isExpandingFullyAbove here.
val isExpandingFullyAbove =
@@ -483,12 +510,12 @@
val controller =
object : Controller by delegate {
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
- listeners.forEach { it.onLaunchAnimationStart() }
+ listener?.onLaunchAnimationStart()
delegate.onLaunchAnimationStart(isExpandingFullyAbove)
}
override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
- listeners.forEach { it.onLaunchAnimationEnd() }
+ listener?.onLaunchAnimationEnd()
iCallback?.invoke()
delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
}
@@ -505,7 +532,7 @@
}
navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) }
- listeners.forEach { it.onLaunchAnimationProgress(linearProgress) }
+ listener?.onLaunchAnimationProgress(linearProgress)
delegate.onLaunchAnimationProgress(state, progress, linearProgress)
}
}
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/Expandable.kt b/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/Expandable.kt
index 8f9a4da..d31ca51 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/Expandable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/Expandable.kt
@@ -20,13 +20,20 @@
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroupOverlay
+import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.LocalMinimumTouchTargetEnforcement
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
@@ -34,46 +41,71 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCompositionContext
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.CornerRadius
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.RoundRect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Outline
+import androidx.compose.ui.graphics.Path
+import androidx.compose.ui.graphics.PathOperation
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.drawOutline
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.layout.boundsInRoot
+import androidx.compose.ui.layout.findRootCoordinates
+import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewTreeLifecycleOwner
import androidx.lifecycle.ViewTreeViewModelStoreOwner
-import androidx.savedstate.ViewTreeSavedStateRegistryOwner
+import com.android.systemui.animation.Expandable
import com.android.systemui.animation.LaunchAnimator
+import kotlin.math.max
import kotlin.math.min
+import kotlin.math.roundToInt
/**
* Create an expandable shape that can launch into an Activity or a Dialog.
*
+ * If this expandable should be expanded when it is clicked directly, then you should specify a
+ * [onClick] handler, which will ensure that this expandable interactive size and background size
+ * are consistent with the M3 components (48dp and 40dp respectively).
+ *
+ * If this expandable should be expanded when a children component is clicked, like a button inside
+ * the expandable, then you can use the Expandable parameter passed to the [content] lambda.
+ *
* Example:
* ```
* Expandable(
* color = MaterialTheme.colorScheme.primary,
* shape = RoundedCornerShape(16.dp),
- * ) { controller ->
- * Row(
- * Modifier
- * // For activities:
- * .clickable { activityStarter.startActivity(intent, controller.forActivity()) }
*
- * // For dialogs:
- * .clickable { dialogLaunchAnimator.show(dialog, controller.forDialog()) }
- * ) { ... }
+ * // For activities:
+ * onClick = { expandable ->
+ * activityStarter.startActivity(intent, expandable.activityLaunchController())
+ * },
+ *
+ * // For dialogs:
+ * onClick = { expandable ->
+ * dialogLaunchAnimator.show(dialog, controller.dialogLaunchController())
+ * },
+ * ) {
+ * ...
* }
* ```
*
@@ -86,11 +118,16 @@
shape: Shape,
modifier: Modifier = Modifier,
contentColor: Color = contentColorFor(color),
- content: @Composable (ExpandableController) -> Unit,
+ borderStroke: BorderStroke? = null,
+ onClick: ((Expandable) -> Unit)? = null,
+ interactionSource: MutableInteractionSource? = null,
+ content: @Composable (Expandable) -> Unit,
) {
Expandable(
- rememberExpandableController(color, shape, contentColor),
+ rememberExpandableController(color, shape, contentColor, borderStroke),
modifier,
+ onClick,
+ interactionSource,
content,
)
}
@@ -119,11 +156,14 @@
* @sample com.android.systemui.compose.gallery.ActivityLaunchScreen
* @sample com.android.systemui.compose.gallery.DialogLaunchScreen
*/
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Expandable(
controller: ExpandableController,
modifier: Modifier = Modifier,
- content: @Composable (ExpandableController) -> Unit,
+ onClick: ((Expandable) -> Unit)? = null,
+ interactionSource: MutableInteractionSource? = null,
+ content: @Composable (Expandable) -> Unit,
) {
val controller = controller as ExpandableControllerImpl
val color = controller.color
@@ -137,12 +177,34 @@
CompositionLocalProvider(
LocalContentColor provides contentColor,
) {
- content(controller)
+ // We make sure that the content itself (wrapped by the background) is at least
+ // 40.dp, which is the same as the M3 buttons. This applies even if onClick is
+ // null, to make it easier to write expandables that are sometimes clickable and
+ // sometimes not. There shouldn't be any Expandable smaller than 40dp because if
+ // the expandable is not clickable directly, then something in its content should
+ // be (and with a size >= 40dp).
+ val minSize = 40.dp
+ Box(
+ Modifier.defaultMinSize(minWidth = minSize, minHeight = minSize),
+ contentAlignment = Alignment.Center,
+ ) {
+ content(controller.expandable)
+ }
}
}
- val thisExpandableSize by remember {
- derivedStateOf { controller.boundsInComposeViewRoot.value.size }
+ var thisExpandableSize by remember { mutableStateOf(Size.Zero) }
+
+ /** Set the current element size as this Expandable size. */
+ fun Modifier.updateExpandableSize(): Modifier {
+ return this.onGloballyPositioned { coords ->
+ thisExpandableSize =
+ coords
+ .findRootCoordinates()
+ // Make sure that we report the actual size, and not the visual/clipped one.
+ .localBoundingBoxOf(coords, clipBounds = false)
+ .size
+ }
}
// Make sure we don't read animatorState directly here to avoid recomposition every time the
@@ -153,22 +215,42 @@
}
}
+ // If this expandable is expanded when it's being directly clicked on, let's ensure that it has
+ // the minimum interactive size followed by all M3 components (48.dp).
+ val minInteractiveSizeModifier =
+ if (onClick != null && LocalMinimumTouchTargetEnforcement.current) {
+ // TODO(b/242040009): Replace this by Modifier.minimumInteractiveComponentSize() once
+ // http://aosp/2305511 is available.
+ val minTouchSize = LocalViewConfiguration.current.minimumTouchTargetSize
+ Modifier.layout { measurable, constraints ->
+ // Copied from androidx.compose.material3.InteractiveComponentSize.kt
+ val placeable = measurable.measure(constraints)
+ val width = maxOf(placeable.width, minTouchSize.width.roundToPx())
+ val height = maxOf(placeable.height, minTouchSize.height.roundToPx())
+ layout(width, height) {
+ val centerX = ((width - placeable.width) / 2f).roundToInt()
+ val centerY = ((height - placeable.height) / 2f).roundToInt()
+ placeable.place(centerX, centerY)
+ }
+ }
+ } else {
+ Modifier
+ }
+
when {
isAnimating -> {
// Don't compose the movable content during the animation, as it should be composed only
// once at all times. We make this spacer exactly the same size as this Expandable when
// it is visible.
Spacer(
- modifier
- .clip(shape)
- .requiredSize(with(controller.density) { thisExpandableSize.toDpSize() })
+ modifier.requiredSize(with(controller.density) { thisExpandableSize.toDpSize() })
)
// The content and its animated background in the overlay. We draw it only when we are
// animating.
AnimatedContentInOverlay(
color,
- thisExpandableSize,
+ controller.boundsInComposeViewRoot.value.size,
controller.animatorState,
controller.overlay.value
?: error("AnimatedContentInOverlay shouldn't be composed with null overlay."),
@@ -182,6 +264,8 @@
controller.isDialogShowing.value -> {
Box(
modifier
+ .updateExpandableSize()
+ .then(minInteractiveSizeModifier)
.drawWithContent { /* Don't draw anything when the dialog is shown. */}
.onGloballyPositioned {
controller.boundsInComposeViewRoot.value = it.boundsInRoot()
@@ -189,11 +273,36 @@
) { wrappedContent(controller) }
}
else -> {
- Box(
- modifier.clip(shape).background(color, shape).onGloballyPositioned {
- controller.boundsInComposeViewRoot.value = it.boundsInRoot()
+ val clickModifier =
+ if (onClick != null) {
+ if (interactionSource != null) {
+ // If the caller provided an interaction source, then that means that they
+ // will draw the click indication themselves.
+ Modifier.clickable(interactionSource, indication = null) {
+ onClick(controller.expandable)
+ }
+ } else {
+ // If no interaction source is provided, we draw the default indication (a
+ // ripple) and make sure it's clipped by the expandable shape.
+ Modifier.clip(shape).clickable { onClick(controller.expandable) }
+ }
+ } else {
+ Modifier
}
- ) { wrappedContent(controller) }
+
+ Box(
+ modifier
+ .updateExpandableSize()
+ .then(minInteractiveSizeModifier)
+ .then(clickModifier)
+ .background(color, shape)
+ .border(controller)
+ .onGloballyPositioned {
+ controller.boundsInComposeViewRoot.value = it.boundsInRoot()
+ },
+ ) {
+ wrappedContent(controller)
+ }
}
}
}
@@ -205,7 +314,7 @@
sizeInOriginalLayout: Size,
animatorState: State<LaunchAnimator.State?>,
overlay: ViewGroupOverlay,
- controller: ExpandableController,
+ controller: ExpandableControllerImpl,
content: @Composable (ExpandableController) -> Unit,
composeViewRoot: View,
onOverlayComposeViewChanged: (View?) -> Unit,
@@ -255,24 +364,7 @@
return@drawWithContent
}
- val topRadius = animatorState.topCornerRadius
- val bottomRadius = animatorState.bottomCornerRadius
- if (topRadius == bottomRadius) {
- // Shortcut to avoid Outline calculation and allocation.
- val cornerRadius = CornerRadius(topRadius)
- drawRoundRect(color, cornerRadius = cornerRadius)
- } else {
- val shape =
- RoundedCornerShape(
- topStart = topRadius,
- topEnd = topRadius,
- bottomStart = bottomRadius,
- bottomEnd = bottomRadius,
- )
- val outline = shape.createOutline(size, layoutDirection, this)
- drawOutline(outline, color = color)
- }
-
+ drawBackground(animatorState, color, controller.borderStroke)
drawContent()
},
// We center the content in the expanding container.
@@ -361,3 +453,107 @@
overlay.remove(view)
return current as ViewGroup
}
+
+private fun Modifier.border(controller: ExpandableControllerImpl): Modifier {
+ return if (controller.borderStroke != null) {
+ this.border(controller.borderStroke, controller.shape)
+ } else {
+ this
+ }
+}
+
+private fun ContentDrawScope.drawBackground(
+ animatorState: LaunchAnimator.State,
+ color: Color,
+ border: BorderStroke?,
+) {
+ val topRadius = animatorState.topCornerRadius
+ val bottomRadius = animatorState.bottomCornerRadius
+ if (topRadius == bottomRadius) {
+ // Shortcut to avoid Outline calculation and allocation.
+ val cornerRadius = CornerRadius(topRadius)
+
+ // Draw the background.
+ drawRoundRect(color, cornerRadius = cornerRadius)
+
+ // Draw the border.
+ if (border != null) {
+ // Copied from androidx.compose.foundation.Border.kt
+ val strokeWidth = border.width.toPx()
+ val halfStroke = strokeWidth / 2
+ val borderStroke = Stroke(strokeWidth)
+
+ drawRoundRect(
+ brush = border.brush,
+ topLeft = Offset(halfStroke, halfStroke),
+ size = Size(size.width - strokeWidth, size.height - strokeWidth),
+ cornerRadius = cornerRadius.shrink(halfStroke),
+ style = borderStroke
+ )
+ }
+ } else {
+ val shape =
+ RoundedCornerShape(
+ topStart = topRadius,
+ topEnd = topRadius,
+ bottomStart = bottomRadius,
+ bottomEnd = bottomRadius,
+ )
+ val outline = shape.createOutline(size, layoutDirection, this)
+
+ // Draw the background.
+ drawOutline(outline, color = color)
+
+ // Draw the border.
+ if (border != null) {
+ // Copied from androidx.compose.foundation.Border.kt.
+ val strokeWidth = border.width.toPx()
+ val path =
+ createRoundRectPath(
+ (outline as Outline.Rounded).roundRect,
+ strokeWidth,
+ )
+
+ drawPath(path, border.brush)
+ }
+ }
+}
+
+/**
+ * Helper method that creates a round rect with the inner region removed by the given stroke width.
+ *
+ * Copied from androidx.compose.foundation.Border.kt.
+ */
+private fun createRoundRectPath(
+ roundedRect: RoundRect,
+ strokeWidth: Float,
+): Path {
+ return Path().apply {
+ addRoundRect(roundedRect)
+ val insetPath =
+ Path().apply { addRoundRect(createInsetRoundedRect(strokeWidth, roundedRect)) }
+ op(this, insetPath, PathOperation.Difference)
+ }
+}
+
+/* Copied from androidx.compose.foundation.Border.kt. */
+private fun createInsetRoundedRect(widthPx: Float, roundedRect: RoundRect) =
+ RoundRect(
+ left = widthPx,
+ top = widthPx,
+ right = roundedRect.width - widthPx,
+ bottom = roundedRect.height - widthPx,
+ topLeftCornerRadius = roundedRect.topLeftCornerRadius.shrink(widthPx),
+ topRightCornerRadius = roundedRect.topRightCornerRadius.shrink(widthPx),
+ bottomLeftCornerRadius = roundedRect.bottomLeftCornerRadius.shrink(widthPx),
+ bottomRightCornerRadius = roundedRect.bottomRightCornerRadius.shrink(widthPx)
+ )
+
+/**
+ * Helper method to shrink the corner radius by the given value, clamping to 0 if the resultant
+ * corner radius would be negative.
+ *
+ * Copied from androidx.compose.foundation.Border.kt.
+ */
+private fun CornerRadius.shrink(value: Float): CornerRadius =
+ CornerRadius(max(0f, this.x - value), max(0f, this.y - value))
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt b/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt
index d6db574..f75b3a8 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt
@@ -20,6 +20,7 @@
import android.view.ViewGroup
import android.view.ViewGroupOverlay
import android.view.ViewRootImpl
+import androidx.compose.foundation.BorderStroke
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
@@ -62,6 +63,7 @@
color: Color,
shape: Shape,
contentColor: Color = contentColorFor(color),
+ borderStroke: BorderStroke? = null,
): ExpandableController {
val composeViewRoot = LocalView.current
val density = LocalDensity.current
@@ -87,11 +89,20 @@
val isComposed = remember { mutableStateOf(true) }
DisposableEffect(Unit) { onDispose { isComposed.value = false } }
- return remember(color, contentColor, shape, composeViewRoot, density, layoutDirection) {
+ return remember(
+ color,
+ contentColor,
+ shape,
+ borderStroke,
+ composeViewRoot,
+ density,
+ layoutDirection,
+ ) {
ExpandableControllerImpl(
color,
contentColor,
shape,
+ borderStroke,
composeViewRoot,
density,
animatorState,
@@ -109,6 +120,7 @@
internal val color: Color,
internal val contentColor: Color,
internal val shape: Shape,
+ internal val borderStroke: BorderStroke?,
internal val composeViewRoot: View,
internal val density: Density,
internal val animatorState: MutableState<LaunchAnimator.State?>,
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ViewTreeSavedStateRegistryOwner.kt b/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ViewTreeSavedStateRegistryOwner.kt
new file mode 100644
index 0000000..79f1cad1
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ViewTreeSavedStateRegistryOwner.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.compose.animation
+
+import android.view.View
+import androidx.savedstate.SavedStateRegistryOwner
+import androidx.savedstate.ViewTreeSavedStateRegistryOwner as AndroidXViewTreeSavedStateRegistryOwner
+
+// TODO(b/262222023): Remove this workaround and import the new savedstate libraries in tm-qpr-dev
+// instead.
+object ViewTreeSavedStateRegistryOwner {
+ fun set(view: View, owner: SavedStateRegistryOwner?) {
+ AndroidXViewTreeSavedStateRegistryOwner.set(view, owner)
+ }
+
+ fun get(view: View): SavedStateRegistryOwner? {
+ return AndroidXViewTreeSavedStateRegistryOwner.get(view)
+ }
+}
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/FadingBackground.kt b/packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/FadingBackground.kt
new file mode 100644
index 0000000..121bf2c
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/systemui/compose/modifiers/FadingBackground.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.compose.modifiers
+
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.DrawModifier
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Outline
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.drawOutline
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.platform.InspectorInfo
+import androidx.compose.ui.platform.InspectorValueInfo
+import androidx.compose.ui.platform.debugInspectorInfo
+import androidx.compose.ui.unit.LayoutDirection
+
+/**
+ * Draws a fading [shape] with a solid [color] and [alpha] behind the content.
+ *
+ * @param color color to paint background with
+ * @param alpha alpha of the background
+ * @param shape desired shape of the background
+ */
+fun Modifier.background(
+ color: Color,
+ alpha: () -> Float,
+ shape: Shape = RectangleShape,
+) =
+ this.then(
+ FadingBackground(
+ brush = SolidColor(color),
+ alpha = alpha,
+ shape = shape,
+ inspectorInfo =
+ debugInspectorInfo {
+ name = "background"
+ value = color
+ properties["color"] = color
+ properties["alpha"] = alpha
+ properties["shape"] = shape
+ }
+ )
+ )
+
+private class FadingBackground
+constructor(
+ private val brush: Brush,
+ private val shape: Shape,
+ private val alpha: () -> Float,
+ inspectorInfo: InspectorInfo.() -> Unit
+) : DrawModifier, InspectorValueInfo(inspectorInfo) {
+ // naive cache outline calculation if size is the same
+ private var lastSize: Size? = null
+ private var lastLayoutDirection: LayoutDirection? = null
+ private var lastOutline: Outline? = null
+
+ override fun ContentDrawScope.draw() {
+ if (shape === RectangleShape) {
+ // shortcut to avoid Outline calculation and allocation
+ drawRect()
+ } else {
+ drawOutline()
+ }
+ drawContent()
+ }
+
+ private fun ContentDrawScope.drawRect() {
+ drawRect(brush, alpha = alpha())
+ }
+
+ private fun ContentDrawScope.drawOutline() {
+ val outline =
+ if (size == lastSize && layoutDirection == lastLayoutDirection) {
+ lastOutline!!
+ } else {
+ shape.createOutline(size, layoutDirection, this)
+ }
+ drawOutline(outline, brush = brush, alpha = alpha())
+ lastOutline = outline
+ lastSize = size
+ lastLayoutDirection = layoutDirection
+ }
+
+ override fun hashCode(): Int {
+ var result = brush.hashCode()
+ result = 31 * result + alpha.hashCode()
+ result = 31 * result + shape.hashCode()
+ return result
+ }
+
+ override fun equals(other: Any?): Boolean {
+ val otherModifier = other as? FadingBackground ?: return false
+ return brush == otherModifier.brush &&
+ alpha == otherModifier.alpha &&
+ shape == otherModifier.shape
+ }
+
+ override fun toString(): String = "FadingBackground(brush=$brush, alpha = $alpha, shape=$shape)"
+}
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt b/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt
index b8639e6..caa7e5f 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt
+++ b/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/AndroidColorScheme.kt
@@ -65,10 +65,12 @@
val colorForeground = getColor(context, R.attr.colorForeground)
val colorForegroundInverse = getColor(context, R.attr.colorForegroundInverse)
- private fun getColor(context: Context, attr: Int): Color {
- val ta = context.obtainStyledAttributes(intArrayOf(attr))
- @ColorInt val color = ta.getColor(0, 0)
- ta.recycle()
- return Color(color)
+ companion object {
+ fun getColor(context: Context, attr: Int): Color {
+ val ta = context.obtainStyledAttributes(intArrayOf(attr))
+ @ColorInt val color = ta.getColor(0, 0)
+ ta.recycle()
+ return Color(color)
+ }
}
}
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/Color.kt b/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/Color.kt
new file mode 100644
index 0000000..de47cce
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/systemui/compose/theme/Color.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.compose.theme
+
+import android.annotation.AttrRes
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+
+/** Read the [Color] from the given [attribute]. */
+@Composable
+@ReadOnlyComposable
+fun colorAttr(@AttrRes attribute: Int): Color {
+ return AndroidColorScheme.getColor(LocalContext.current, attribute)
+}
diff --git a/packages/SystemUI/compose/features/AndroidManifest.xml b/packages/SystemUI/compose/features/AndroidManifest.xml
index 278a89f..c1a9ec5 100644
--- a/packages/SystemUI/compose/features/AndroidManifest.xml
+++ b/packages/SystemUI/compose/features/AndroidManifest.xml
@@ -16,43 +16,6 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
-
package="com.android.systemui.compose.features">
- <application
- android:name="android.app.Application"
- android:appComponentFactory="androidx.core.app.AppComponentFactory"
- tools:replace="android:name,android:appComponentFactory">
- <!-- Disable providers from SystemUI -->
- <provider android:name="com.android.systemui.keyguard.KeyguardSliceProvider"
- android:authorities="com.android.systemui.test.keyguard.disabled"
- android:enabled="false"
- tools:replace="android:authorities"
- tools:node="remove" />
- <provider android:name="com.google.android.systemui.keyguard.KeyguardSliceProviderGoogle"
- android:authorities="com.android.systemui.test.keyguard.disabled"
- android:enabled="false"
- tools:replace="android:authorities"
- tools:node="remove" />
- <provider android:name="com.android.systemui.keyguard.KeyguardQuickAffordanceProvider"
- android:authorities="com.android.systemui.test.keyguard.quickaffordance.disabled"
- android:enabled="false"
- tools:replace="android:authorities"
- tools:node="remove" />
- <provider android:name="com.android.keyguard.clock.ClockOptionsProvider"
- android:authorities="com.android.systemui.test.keyguard.clock.disabled"
- android:enabled="false"
- tools:replace="android:authorities"
- tools:node="remove" />
- <provider android:name="com.android.systemui.people.PeopleProvider"
- android:authorities="com.android.systemui.test.people.disabled"
- android:enabled="false"
- tools:replace="android:authorities"
- tools:node="remove" />
- <provider android:name="androidx.core.content.FileProvider"
- android:authorities="com.android.systemui.test.fileprovider.disabled"
- android:enabled="false"
- tools:replace="android:authorities"
- tools:node="remove"/>
- </application>
+
</manifest>
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/ContentDescription.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/ContentDescription.kt
new file mode 100644
index 0000000..4a5ad65
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/ContentDescription.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.common.ui.compose
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.res.stringResource
+import com.android.systemui.common.shared.model.ContentDescription
+
+/** Returns the loaded [String] or `null` if there isn't one. */
+@Composable
+fun ContentDescription.load(): String? {
+ return when (this) {
+ is ContentDescription.Loaded -> description
+ is ContentDescription.Resource -> stringResource(res)
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Icon.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Icon.kt
new file mode 100644
index 0000000..6e83124
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Icon.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.common.ui.compose
+
+import androidx.compose.material3.Icon
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.asImageBitmap
+import androidx.compose.ui.res.painterResource
+import androidx.core.graphics.drawable.toBitmap
+import com.android.systemui.common.shared.model.Icon
+
+/**
+ * Icon composable that draws [icon] using [tint].
+ *
+ * Note: You can use [Color.Unspecified] to disable the tint and keep the original icon colors.
+ */
+@Composable
+fun Icon(
+ icon: Icon,
+ modifier: Modifier = Modifier,
+ tint: Color = LocalContentColor.current,
+) {
+ val contentDescription = icon.contentDescription?.load()
+ when (icon) {
+ is Icon.Loaded -> {
+ Icon(icon.drawable.toBitmap().asImageBitmap(), contentDescription, modifier, tint)
+ }
+ is Icon.Resource -> Icon(painterResource(icon.res), contentDescription, modifier, tint)
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
index 2bf1937..2aac46e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
@@ -53,7 +53,6 @@
import com.android.systemui.compose.theme.LocalAndroidColorScheme
import com.android.systemui.people.ui.viewmodel.PeopleTileViewModel
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
-import kotlinx.coroutines.flow.collect
/**
* Compose the screen associated to a [PeopleViewModel].
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
new file mode 100644
index 0000000..654b723
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.footer.ui.compose
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.LocalIndication
+import androidx.compose.foundation.indication
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.drawWithContent
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.layout.layout
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.constrainHeight
+import androidx.compose.ui.unit.constrainWidth
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.em
+import androidx.compose.ui.unit.sp
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.R
+import com.android.systemui.animation.Expandable
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.compose.animation.Expandable
+import com.android.systemui.compose.modifiers.background
+import com.android.systemui.compose.theme.LocalAndroidColorScheme
+import com.android.systemui.compose.theme.colorAttr
+import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel
+import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsForegroundServicesButtonViewModel
+import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel
+import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
+import kotlinx.coroutines.launch
+
+/** The Quick Settings footer actions row. */
+@Composable
+fun FooterActions(
+ viewModel: FooterActionsViewModel,
+ qsVisibilityLifecycleOwner: LifecycleOwner,
+ modifier: Modifier = Modifier,
+) {
+ val context = LocalContext.current
+
+ // Collect visibility and alphas as soon as we are composed, even when not visible.
+ val isVisible by viewModel.isVisible.collectAsState()
+ val alpha by viewModel.alpha.collectAsState()
+ val backgroundAlpha = viewModel.backgroundAlpha.collectAsState()
+
+ var security by remember { mutableStateOf<FooterActionsSecurityButtonViewModel?>(null) }
+ var foregroundServices by remember {
+ mutableStateOf<FooterActionsForegroundServicesButtonViewModel?>(null)
+ }
+ var userSwitcher by remember { mutableStateOf<FooterActionsButtonViewModel?>(null) }
+
+ LaunchedEffect(
+ context,
+ qsVisibilityLifecycleOwner,
+ viewModel,
+ viewModel.security,
+ viewModel.foregroundServices,
+ viewModel.userSwitcher,
+ ) {
+ launch {
+ // Listen for dialog requests as soon as we are composed, even when not visible.
+ viewModel.observeDeviceMonitoringDialogRequests(context)
+ }
+
+ // Listen for model changes only when QS are visible.
+ qsVisibilityLifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ launch { viewModel.security.collect { security = it } }
+ launch { viewModel.foregroundServices.collect { foregroundServices = it } }
+ launch { viewModel.userSwitcher.collect { userSwitcher = it } }
+ }
+ }
+
+ val backgroundColor = colorAttr(R.attr.underSurfaceColor)
+ val contentColor = LocalAndroidColorScheme.current.textColorPrimary
+ val backgroundTopRadius = dimensionResource(R.dimen.qs_corner_radius)
+ val backgroundModifier =
+ remember(
+ backgroundColor,
+ backgroundAlpha,
+ backgroundTopRadius,
+ ) {
+ Modifier.background(
+ backgroundColor,
+ backgroundAlpha::value,
+ RoundedCornerShape(topStart = backgroundTopRadius, topEnd = backgroundTopRadius),
+ )
+ }
+
+ Row(
+ modifier
+ .fillMaxWidth()
+ .graphicsLayer { this.alpha = alpha }
+ .drawWithContent {
+ if (isVisible) {
+ drawContent()
+ }
+ }
+ .then(backgroundModifier)
+ .padding(
+ top = dimensionResource(R.dimen.qs_footer_actions_top_padding),
+ bottom = dimensionResource(R.dimen.qs_footer_actions_bottom_padding),
+ )
+ .layout { measurable, constraints ->
+ // All buttons have a 4dp padding to increase their touch size. To be consistent
+ // with the View implementation, we want to left-most and right-most buttons to be
+ // visually aligned with the left and right sides of this row. So we let this
+ // component be 2*4dp wider and then offset it by -4dp to the start.
+ val inset = 4.dp.roundToPx()
+ val additionalWidth = inset * 2
+ val newConstraints =
+ if (constraints.hasBoundedWidth) {
+ constraints.copy(maxWidth = constraints.maxWidth + additionalWidth)
+ } else {
+ constraints
+ }
+ val placeable = measurable.measure(newConstraints)
+
+ val width = constraints.constrainWidth(placeable.width - additionalWidth)
+ val height = constraints.constrainHeight(placeable.height)
+ layout(width, height) { placeable.place(-inset, 0) }
+ },
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ CompositionLocalProvider(
+ LocalContentColor provides contentColor,
+ ) {
+ if (security == null && foregroundServices == null) {
+ Spacer(Modifier.weight(1f))
+ }
+
+ security?.let { SecurityButton(it, Modifier.weight(1f)) }
+ foregroundServices?.let { ForegroundServicesButton(it) }
+ userSwitcher?.let { IconButton(it) }
+ IconButton(viewModel.settings)
+ viewModel.power?.let { IconButton(it) }
+ }
+ }
+}
+
+/** The security button. */
+@Composable
+private fun SecurityButton(
+ model: FooterActionsSecurityButtonViewModel,
+ modifier: Modifier = Modifier,
+) {
+ val onClick: ((Expandable) -> Unit)? =
+ model.onClick?.let { onClick ->
+ val context = LocalContext.current
+ { expandable -> onClick(context, expandable) }
+ }
+
+ TextButton(
+ model.icon,
+ model.text,
+ showNewDot = false,
+ onClick = onClick,
+ modifier,
+ )
+}
+
+/** The foreground services button. */
+@Composable
+private fun RowScope.ForegroundServicesButton(
+ model: FooterActionsForegroundServicesButtonViewModel,
+) {
+ if (model.displayText) {
+ TextButton(
+ Icon.Resource(R.drawable.ic_info_outline, contentDescription = null),
+ model.text,
+ showNewDot = model.hasNewChanges,
+ onClick = model.onClick,
+ Modifier.weight(1f),
+ )
+ } else {
+ NumberButton(
+ model.foregroundServicesCount,
+ showNewDot = model.hasNewChanges,
+ onClick = model.onClick,
+ )
+ }
+}
+
+/** A button with an icon. */
+@Composable
+private fun IconButton(
+ model: FooterActionsButtonViewModel,
+ modifier: Modifier = Modifier,
+) {
+ Expandable(
+ color = colorAttr(model.backgroundColor),
+ shape = CircleShape,
+ onClick = model.onClick,
+ modifier = modifier,
+ ) {
+ val tint = model.iconTint?.let { Color(it) } ?: Color.Unspecified
+ Icon(
+ model.icon,
+ tint = tint,
+ modifier = Modifier.size(20.dp),
+ )
+ }
+}
+
+/** A button with a number an an optional dot (to indicate new changes). */
+@Composable
+private fun NumberButton(
+ number: Int,
+ showNewDot: Boolean,
+ onClick: (Expandable) -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ // By default Expandable will show a ripple above its content when clicked, and clip the content
+ // with the shape of the expandable. In this case we also want to show a "new changes dot"
+ // outside of the shape, so we can't clip. To work around that we can pass our own interaction
+ // source and draw the ripple indication ourselves above the text but below the "new changes
+ // dot".
+ val interactionSource = remember { MutableInteractionSource() }
+
+ Expandable(
+ color = colorAttr(R.attr.offStateColor),
+ shape = CircleShape,
+ onClick = onClick,
+ interactionSource = interactionSource,
+ modifier = modifier,
+ ) {
+ Box(Modifier.size(40.dp)) {
+ Box(
+ Modifier.fillMaxSize()
+ .clip(CircleShape)
+ .indication(
+ interactionSource,
+ LocalIndication.current,
+ )
+ ) {
+ Text(
+ number.toString(),
+ modifier = Modifier.align(Alignment.Center),
+ style = MaterialTheme.typography.bodyLarge,
+ color = LocalAndroidColorScheme.current.textColorPrimary,
+ // TODO(b/242040009): This should only use a standard text style instead and
+ // should not override the text size.
+ fontSize = 18.sp,
+ )
+ }
+
+ if (showNewDot) {
+ NewChangesDot(Modifier.align(Alignment.BottomEnd))
+ }
+ }
+ }
+}
+
+/** A dot that indicates new changes. */
+@Composable
+private fun NewChangesDot(modifier: Modifier = Modifier) {
+ val contentDescription = stringResource(R.string.fgs_dot_content_description)
+ val color = LocalAndroidColorScheme.current.colorAccentTertiary
+
+ Canvas(modifier.size(12.dp).semantics { this.contentDescription = contentDescription }) {
+ drawCircle(color)
+ }
+}
+
+/** A larger button with an icon, some text and an optional dot (to indicate new changes). */
+@Composable
+private fun TextButton(
+ icon: Icon,
+ text: String,
+ showNewDot: Boolean,
+ onClick: ((Expandable) -> Unit)?,
+ modifier: Modifier = Modifier,
+) {
+ Expandable(
+ shape = CircleShape,
+ color = colorAttr(R.attr.underSurfaceColor),
+ contentColor = LocalAndroidColorScheme.current.textColorSecondary,
+ borderStroke = BorderStroke(1.dp, LocalAndroidColorScheme.current.colorBackground),
+ modifier = modifier.padding(horizontal = 4.dp),
+ onClick = onClick,
+ ) {
+ Row(
+ Modifier.padding(horizontal = dimensionResource(R.dimen.qs_footer_padding)),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Icon(icon, Modifier.padding(end = 12.dp).size(20.dp))
+
+ Text(
+ text,
+ Modifier.weight(1f),
+ style = MaterialTheme.typography.bodyMedium,
+ // TODO(b/242040009): Remove this letter spacing. We should only use the M3 text
+ // styles without modifying them.
+ letterSpacing = 0.01.em,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+
+ if (showNewDot) {
+ NewChangesDot(Modifier.padding(start = 8.dp))
+ }
+
+ if (onClick != null) {
+ Icon(
+ painterResource(com.android.internal.R.drawable.ic_chevron_end),
+ contentDescription = null,
+ Modifier.padding(start = 8.dp).size(20.dp),
+ )
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/features/tests/AndroidManifest.xml b/packages/SystemUI/compose/features/tests/AndroidManifest.xml
index 5e54c1f..2fa475d 100644
--- a/packages/SystemUI/compose/features/tests/AndroidManifest.xml
+++ b/packages/SystemUI/compose/features/tests/AndroidManifest.xml
@@ -15,10 +15,46 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.systemui.compose.features.tests" >
- <application>
+ <application
+ android:name="android.app.Application"
+ android:appComponentFactory="androidx.core.app.AppComponentFactory"
+ tools:replace="android:name,android:appComponentFactory">
<uses-library android:name="android.test.runner" />
+
+ <!-- Disable providers from SystemUI -->
+ <provider android:name="com.android.systemui.keyguard.KeyguardSliceProvider"
+ android:authorities="com.android.systemui.test.keyguard.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+ <provider android:name="com.google.android.systemui.keyguard.KeyguardSliceProviderGoogle"
+ android:authorities="com.android.systemui.test.keyguard.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+ <provider android:name="com.android.systemui.keyguard.KeyguardQuickAffordanceProvider"
+ android:authorities="com.android.systemui.test.keyguard.quickaffordance.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+ <provider android:name="com.android.keyguard.clock.ClockOptionsProvider"
+ android:authorities="com.android.systemui.test.keyguard.clock.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+ <provider android:name="com.android.systemui.people.PeopleProvider"
+ android:authorities="com.android.systemui.test.people.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove" />
+ <provider android:name="androidx.core.content.FileProvider"
+ android:authorities="com.android.systemui.test.fileprovider.disabled"
+ android:enabled="false"
+ tools:replace="android:authorities"
+ tools:node="remove"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt
index cb1a5f9..ec5e703 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt
@@ -58,7 +58,9 @@
flags: List<KeyguardQuickAffordanceProviderClient.Flag> =
listOf(
KeyguardQuickAffordanceProviderClient.Flag(
- name = KeyguardQuickAffordanceProviderContract.FlagsTable.FLAG_NAME_FEATURE_ENABLED,
+ name =
+ KeyguardQuickAffordanceProviderContract.FlagsTable
+ .FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
value = true,
)
),
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt
index 17be74b..e197752 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt
@@ -145,10 +145,17 @@
const val TABLE_NAME = "flags"
val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
+ /** Flag denoting whether the Wallpaper Picker should use the new, revamped UI. */
+ const val FLAG_NAME_REVAMPED_WALLPAPER_UI = "revamped_wallpaper_ui"
+
/**
* Flag denoting whether the customizable lock screen quick affordances feature is enabled.
*/
- const val FLAG_NAME_FEATURE_ENABLED = "is_feature_enabled"
+ const val FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED =
+ "is_custom_lock_screen_quick_affordances_feature_enabled"
+
+ /** Flag denoting whether the customizable clocks feature is enabled. */
+ const val FLAG_NAME_CUSTOM_CLOCKS_ENABLED = "is_custom_clocks_feature_enabled"
object Columns {
/** String. Unique ID for the flag. */
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardQuickAffordancePreviewConstants.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardQuickAffordancePreviewConstants.kt
new file mode 100644
index 0000000..18e8a96
--- /dev/null
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardQuickAffordancePreviewConstants.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.shared.quickaffordance.shared.model
+
+object KeyguardQuickAffordancePreviewConstants {
+ const val MESSAGE_ID_SLOT_SELECTED = 1337
+ const val KEY_SLOT_ID = "slot_id"
+ const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id"
+}
diff --git a/packages/SystemUI/res-keyguard/layout/fsi_chrome_view.xml b/packages/SystemUI/res-keyguard/layout/fsi_chrome_view.xml
new file mode 100644
index 0000000..4ff2967
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/fsi_chrome_view.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.systemui.statusbar.notification.fsi.FsiChromeView android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="50dp"
+ android:orientation="vertical"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:id="@+id/fsi_chrome"
+ android:layout_height="50dp"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/fsi_app_icon"
+ android:layout_width="50dp"
+ android:layout_height="match_parent"
+ android:contentDescription="@null" />
+
+ <TextView
+ android:id="@+id/fsi_app_name"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:padding="10dp"
+ android:textSize="22dp"
+ android:gravity="center"
+ android:textColor="#FFFFFF"
+ android:text="AppName" />
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button
+ android:id="@+id/fsi_fullscreen_button"
+ android:layout_width="100dp"
+ android:layout_height="match_parent"
+ android:text="fullscreen" />
+
+ <Button
+ android:id="@+id/fsi_dismiss_button"
+ android:layout_width="100dp"
+ android:layout_height="match_parent"
+ android:text="dismiss" />
+
+ </LinearLayout>
+
+</com.android.systemui.statusbar.notification.fsi.FsiChromeView>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index 25c7528b..ea358f6 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans vinnig"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans stadig"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laaiproses is onderbreek om battery te beskerm"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Druk Kieslys om te ontsluit."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netwerk is gesluit"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Geen SIM-kaart nie"</string>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index fb2a34f..8d1c9aa 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -30,7 +30,7 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ኃይል በመሙላት ላይ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • በፍጥነት ኃይልን በመሙላት ላይ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • በዝግታ ኃይልን በመሙላት ላይ"</string>
- <!-- no translation found for keyguard_plugged_in_charging_limited (1657547879230699837) -->
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
<skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ለመክፈት ምናሌ ተጫን።"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"አውታረ መረብ ተቆልፏል"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 5faabec..fe2e6e6 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن سريعًا"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن ببطء"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • تم إيقاف الشحن مؤقتًا لحماية البطارية"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"اضغط على \"القائمة\" لإلغاء التأمين."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"الشبكة مؤمّنة"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ليست هناك شريحة SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index 60e7463..a2f7fc4 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চ্চার্জ কৰি থকা হৈছে"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্ৰুত গতিৰে চ্চাৰ্জ কৰি থকা হৈছে"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • লাহে লাহে চ্চাৰ্জ কৰি থকা হৈছে"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • বেটাৰী সুৰক্ষিত কৰিবলৈ চাৰ্জিং পজ কৰা হৈছে"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক কৰিবলৈ মেনু টিপক।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটৱর্ক লক কৰা অৱস্থাত আছে"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"কোনো ছিম কাৰ্ড নাই"</string>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index bc428ad..9b81c35 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Enerji yığır"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sürətlə enerji yığır"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Yavaş enerji yığır"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Batareyanı qorumaq üçün şarj durdurulub"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmaq üçün Menyu düyməsinə basın."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Şəbəkə kilidlidir"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM kart yoxdur."</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index 24f9fe9..01bd907 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -20,75 +20,76 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Unesite PIN"</string>
- <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Unesite šablon"</string>
- <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Unesite lozinku"</string>
- <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Nevažeća kartica."</string>
- <string name="keyguard_charged" msgid="5478247181205188995">"Napunjena je"</string>
- <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bežično punjenje"</string>
- <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Puni se"</string>
- <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Puni se"</string>
- <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Brzo se puni"</string>
- <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sporo se puni"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje je pauzirano da bi se zaštitila baterija"</string>
- <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite Meni da biste otključali."</string>
- <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
- <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nema SIM kartice"</string>
- <string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Umetnite SIM karticu."</string>
- <string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM kartica nedostaje ili ne može da se pročita. Umetnite SIM karticu."</string>
- <string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM kartica je neupotrebljiva."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"SIM kartica je trajno onemogućena.\nObratite se dobavljaču usluge bežične mreže da biste dobili drugu SIM karticu."</string>
- <string name="keyguard_sim_locked_message" msgid="4343544458476911044">"SIM kartica je zaključana."</string>
- <string name="keyguard_sim_puk_locked_message" msgid="6253830777745450550">"SIM kartica je zaključana PUK kodom."</string>
- <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"SIM kartica se otključava…"</string>
- <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"Oblast za PIN"</string>
- <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Lozinka za uređaj"</string>
- <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"Oblast za PIN za SIM"</string>
- <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"Oblast za PUK za SIM"</string>
- <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Izbriši"</string>
- <string name="disable_carrier_button_text" msgid="7153361131709275746">"Onemogući eSIM"</string>
- <string name="error_disable_esim_title" msgid="3802652622784813119">"Onemogućavanje eSIM-a nije uspelo"</string>
- <string name="error_disable_esim_msg" msgid="2441188596467999327">"eSIM ne može da se onemogući zbog greške."</string>
+ <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Унесите PIN"</string>
+ <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Унесите шаблон"</string>
+ <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Унесите лозинку"</string>
+ <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Неважећа картица."</string>
+ <string name="keyguard_charged" msgid="5478247181205188995">"Напуњена је"</string>
+ <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Бежично пуњење"</string>
+ <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуни се"</string>
+ <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуни се"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо се пуни"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Споро се пуни"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
+ <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притисните Мени да бисте откључали."</string>
+ <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежа је закључана"</string>
+ <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нема SIM картице"</string>
+ <string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Уметните SIM картицу."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM картица недостаје или не може да се прочита. Уметните SIM картицу."</string>
+ <string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM картица је неупотребљива."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"SIM картица је трајно онемогућена.\nОбратите се добављачу услуге бежичне мреже да бисте добили другу SIM картицу."</string>
+ <string name="keyguard_sim_locked_message" msgid="4343544458476911044">"SIM картица је закључана."</string>
+ <string name="keyguard_sim_puk_locked_message" msgid="6253830777745450550">"SIM картица је закључана PUK кодом."</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"SIM картица се откључава…"</string>
+ <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"Област за PIN"</string>
+ <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Лозинка за уређај"</string>
+ <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"Област за PIN за SIM"</string>
+ <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"Област за PUK за SIM"</string>
+ <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Избриши"</string>
+ <string name="disable_carrier_button_text" msgid="7153361131709275746">"Онемогући eSIM"</string>
+ <string name="error_disable_esim_title" msgid="3802652622784813119">"Онемогућавање eSIM-а није успело"</string>
+ <string name="error_disable_esim_msg" msgid="2441188596467999327">"eSIM не може да се онемогући због грешке."</string>
<string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Enter"</string>
- <string name="kg_wrong_pattern" msgid="5907301342430102842">"Pogrešan šablon"</string>
- <string name="kg_wrong_password" msgid="4143127991071670512">"Pogrešna lozinka"</string>
- <string name="kg_wrong_pin" msgid="4160978845968732624">"Pogrešan PIN"</string>
- <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Probajte ponovo za # sekundu.}one{Probajte ponovo za # sekundu.}few{Probajte ponovo za # sekunde.}other{Probajte ponovo za # sekundi.}}"</string>
- <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Unesite PIN za SIM."</string>
- <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Unesite PIN za SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
- <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Onemogućite eSIM da biste uređaj koristili bez mobilne usluge."</string>
- <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM kartica je sada onemogućena. Unesite PUK kôd da biste nastavili. Detaljne informacije potražite od mobilnog operatera."</string>
- <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“ je sada onemogućen. Unesite PUK kôd da biste nastavili. Detaljne informacije potražite od mobilnog operatera."</string>
- <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Unesite željeni PIN kôd"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Potvrdite željeni PIN kôd"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"SIM kartica se otključava…"</string>
- <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Unesite PIN koji ima 4–8 brojeva."</string>
- <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kôd treba da ima 8 ili više brojeva."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Uneli ste pogrešan PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Uneli ste pogrešnu lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Nacrtali ste netačan šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Netačan PIN kôd za SIM. Sada morate da kontaktirate mobilnog operatera da biste otključali uređaj."</string>
- <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Netačan PIN za SIM kôd. Imate još # pokušaj, a onda morate da se obratite mobilnom operateru da biste otključali uređaj.}one{Netačan PIN za SIM kôd. Imate još # pokušaj. }few{Netačan PIN za SIM kôd. Imate još # pokušaja. }other{Netačan PIN za SIM kôd. Imate još # pokušaja. }}"</string>
- <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM kartica je neupotrebljiva. Kontaktirajte mobilnog operatera."</string>
- <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Netačan SIM PUK kôd. Imate još # pokušaj pre nego što SIM kartica postane trajno neupotrebljiva.}one{Netačan PUK kôd za SIM. Imate još # pokušaj pre nego što SIM kartica postane trajno neupotrebljiva.}few{Netačan PUK kôd za SIM. Imate još # pokušaja pre nego što SIM kartica postane trajno neupotrebljiva.}other{Netačan PUK kôd za SIM. Imate još # pokušaja pre nego što SIM kartica postane trajno neupotrebljiva.}}"</string>
- <string name="kg_password_pin_failed" msgid="5136259126330604009">"Radnja sa PIN kodom za SIM nije uspela!"</string>
- <string name="kg_password_puk_failed" msgid="6778867411556937118">"Radnja sa PUK kodom za SIM nije uspela!"</string>
- <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promeni metod unosa"</string>
- <string name="airplane_mode" msgid="2528005343938497866">"Režim rada u avionu"</string>
- <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Treba da unesete šablon kada se uređaj ponovo pokrene"</string>
- <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Treba da unesete PIN kada se uređaj ponovo pokrene"</string>
- <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Treba da unesete lozinku kada se uređaj ponovo pokrene"</string>
- <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Za dodatnu bezbednost koristite šablon"</string>
- <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Za dodatnu bezbednost koristite PIN"</string>
- <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Za dodatnu bezbednost koristite lozinku"</string>
- <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"Administrator je zaključao uređaj"</string>
- <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Uređaj je ručno zaključan"</string>
- <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nije prepoznat"</string>
- <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Otključavanje licem traži pristup kameri u Podešavanjima"</string>
- <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Unesite PIN za SIM. Još # pokušaj i moraćete da se obratite mobilnom operateru da biste otključali uređaj.}one{Unesite PIN za SIM. Imate još # pokušaj.}few{Unesite PIN za SIM. Imate još # pokušaja.}other{Unesite PIN za SIM. Imate još # pokušaja.}}"</string>
- <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaj pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}one{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaj pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}few{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}other{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}}"</string>
- <string name="clock_title_default" msgid="6342735240617459864">"Podrazumevani"</string>
- <string name="clock_title_bubble" msgid="2204559396790593213">"Mehurići"</string>
- <string name="clock_title_analog" msgid="8409262532900918273">"Analogni"</string>
- <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Otključajte uređaj da biste nastavili"</string>
+ <string name="kg_wrong_pattern" msgid="5907301342430102842">"Погрешан шаблон"</string>
+ <string name="kg_wrong_password" msgid="4143127991071670512">"Погрешна лозинка"</string>
+ <string name="kg_wrong_pin" msgid="4160978845968732624">"Погрешан PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Пробајте поново за # секунду.}one{Пробајте поново за # секунду.}few{Пробајте поново за # секунде.}other{Пробајте поново за # секунди.}}"</string>
+ <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Унесите PIN за SIM."</string>
+ <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Унесите PIN за SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+ <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Онемогућите eSIM да бисте уређај користили без мобилне услуге."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM картица је сада онемогућена. Унесите PUK кôд да бисте наставили. Детаљне информације потражите од мобилног оператера."</string>
+ <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“ је сада онемогућен. Унесите PUK кôд да бисте наставили. Детаљне информације потражите од мобилног оператера."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Унесите жељени PIN кôд"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Потврдите жељени PIN кôд"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"SIM картица се откључава…"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Унесите PIN који има 4–8 бројева."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK кôд треба да има 8 или више бројева."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Унели сте погрешан PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Унели сте погрешну лозинку <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Нацртали сте нетачан шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Нетачан PIN кôд за SIM. Сада морате да контактирате мобилног оператера да бисте откључали уређај."</string>
+ <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Нетачан PIN за SIM кôд. Имате још # покушај, а онда морате да се обратите мобилном оператеру да бисте откључали уређај.}one{Нетачан PIN за SIM кôд. Имате још # покушај. }few{Нетачан PIN за SIM кôд. Имате још # покушаја. }other{Нетачан PIN за SIM кôд. Имате још # покушаја. }}"</string>
+ <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM картица је неупотребљива. Контактирајте мобилног оператера."</string>
+ <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Нетачан SIM PUK кôд. Имате још # покушај пре него што SIM картица постане трајно неупотребљива.}one{Нетачан PUK кôд за SIM. Имате још # покушај пре него што SIM картица постане трајно неупотребљива.}few{Нетачан PUK кôд за SIM. Имате још # покушаја пре него што SIM картица постане трајно неупотребљива.}other{Нетачан PUK кôд за SIM. Имате још # покушаја пре него што SIM картица постане трајно неупотребљива.}}"</string>
+ <string name="kg_password_pin_failed" msgid="5136259126330604009">"Радња са PIN кодом за SIM није успела!"</string>
+ <string name="kg_password_puk_failed" msgid="6778867411556937118">"Радња са PUK кодом за SIM није успела!"</string>
+ <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Промени метод уноса"</string>
+ <string name="airplane_mode" msgid="2528005343938497866">"Режим рада у авиону"</string>
+ <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Треба да унесете шаблон када се уређај поново покрене"</string>
+ <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Треба да унесете PIN када се уређај поново покрене"</string>
+ <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Треба да унесете лозинку када се уређај поново покрене"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"За додатну безбедност користите шаблон"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"За додатну безбедност користите PIN"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"За додатну безбедност користите лозинку"</string>
+ <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"Администратор је закључао уређај"</string>
+ <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Уређај је ручно закључан"</string>
+ <string name="kg_face_not_recognized" msgid="7903950626744419160">"Није препознат"</string>
+ <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Откључавање лицем тражи приступ камери у Подешавањима"</string>
+ <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Унесите PIN за SIM. Још # покушај и мораћете да се обратите мобилном оператеру да бисте откључали уређај.}one{Унесите PIN за SIM. Имате још # покушај.}few{Унесите PIN за SIM. Имате још # покушаја.}other{Унесите PIN за SIM. Имате још # покушаја.}}"</string>
+ <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушај пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}one{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушај пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}few{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}other{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}}"</string>
+ <string name="clock_title_default" msgid="6342735240617459864">"Подразумевани"</string>
+ <string name="clock_title_bubble" msgid="2204559396790593213">"Мехурићи"</string>
+ <string name="clock_title_analog" msgid="8409262532900918273">"Аналогни"</string>
+ <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Откључајте уређај да бисте наставили"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index 53ee20f..e5da604 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе зарадка"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе хуткая зарадка"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе павольная зарадка"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Дзеля зберажэння акумулятара зарадка прыпынена"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Націсніце кнопку \"Меню\", каб разблакіраваць."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сетка заблакіравана"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Няма SIM-карты"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index 2dbbb9a..fcd6d57 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се бързо"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се бавно"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зареждането е на пауза с цел запазване на батерията"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Натиснете „Меню“, за да отключите."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежата е заключена"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Няма SIM карта"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index bde5d00..1588f21 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চার্জ হচ্ছে"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্রুত চার্জ হচ্ছে"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ধীরে চার্জ হচ্ছে"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ব্যাটারি সুরক্ষিত রাখতে চার্জিং পজ করা হয়েছে"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক করতে মেনুতে টিপুন।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটওয়ার্ক লক করা আছে"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"কোনো সিম কার্ড নেই"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 6b7f15b..6b88e8b 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Brzo punjenje"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sporo punjenje"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje je pauzirano radi zaštite baterije"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite meni da otključate."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nema SIM kartice"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 0d71e29..0ccf1c1 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant ràpidament"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant lentament"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • La càrrega s\'ha posat en pausa per protegir la bateria"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prem Menú per desbloquejar."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"La xarxa està bloquejada"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No hi ha cap SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index b815328..d130a79 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíjení"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Rychlé nabíjení"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pomalé nabíjení"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíjení bylo kvůli ochraně baterie pozastaveno"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Klávesy odemknete stisknutím tlačítka nabídky."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Síť je blokována"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Chybí SIM karta"</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index bb54fd7..1d65ad4 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader hurtigt"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader langsomt"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladning er sat på pause for at beskytte batteriet"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tryk på menuen for at låse op."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netværket er låst"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Intet SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 57a368e..21e330c 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird geladen"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird schnell geladen"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird langsam geladen"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladevorgang pausiert, um den Akku zu schonen"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Zum Entsperren die Menütaste drücken."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netzwerk gesperrt"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Keine SIM-Karte"</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index efa6e8e..3e6a9ad 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Φόρτιση"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Γρήγορη φόρτιση"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Αργή φόρτιση"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Η φόρτιση τέθηκε σε παύση για την προστασία της μπαταρίας"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Πατήστε \"Μενού\" για ξεκλείδωμα."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Κλειδωμένο δίκτυο"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Δεν υπάρχει SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index e9727e8..5852fef 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging paused to protect battery"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
index f007964..ed5b5c3 100644
--- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
@@ -30,7 +30,7 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging paused to protect battery"</string>
+ <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging optimized to protect battery"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index e9727e8..5852fef 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging paused to protect battery"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index e9727e8..5852fef 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging paused to protect battery"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
index cae6242..d25ff78 100644
--- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
@@ -30,7 +30,7 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging paused to protect battery"</string>
+ <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging optimized to protect battery"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index c80cf19..c609687 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rápidamente"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se detuvo la carga para proteger la batería"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Presiona Menú para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sin tarjeta SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index f766109..bbff08c 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rápidamente"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga pausada para proteger la batería"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pulsa el menú para desbloquear la pantalla."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Falta la tarjeta SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index f9f32d9..4570bd5 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laadimine"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kiirlaadimine"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Aeglane laadimine"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laadimine on aku kaitsmiseks peatatud"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Vajutage avamiseks menüüklahvi."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Võrk on lukus"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM-kaarti pole"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 2492e83..eca4a36 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kargatzen"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bizkor kargatzen"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mantso kargatzen"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bateria babesteko pausatu da kargatze-prozesua"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Desblokeatzeko, sakatu Menua."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Sarea blokeatuta dago"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ez dago SIM txartelik"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index c73b736..83e222d 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ شدن"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ سریع"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • آهستهآهسته شارژ میشود"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • برای محافظت از باتری، شارژ موقتاً متوقف شد"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"برای باز کردن قفل روی «منو» فشار دهید."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"شبکه قفل شد"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"سیمکارت موجود نیست"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index 4df432b..d434dd3 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan nopeasti"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan hitaasti"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lataus keskeytetty akun suojaamiseksi"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Poista lukitus painamalla Valikkoa."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Verkko lukittu"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ei SIM-korttia"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index 71ae6c0..252fea4 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"En recharge : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"En recharge rapide : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"En recharge lente : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charge interrompue pour protéger la pile"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur la touche Menu pour déverrouiller l\'appareil."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Aucune carte SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index b12169a..e112943 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge…"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge rapide…"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge lente"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge suspendue pour protéger la batterie"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur \"Menu\" pour déverrouiller le clavier."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Pas de carte SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index 712df23..fad23f8 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rapidamente"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga en pausa para protexer a batería"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Preme Menú para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada pola rede"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sen tarxeta SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index a9d1103..f85a6c3 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ઝડપથી ચાર્જિંગ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ધીમેથી ચાર્જિંગ"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • બૅટરીની સુરક્ષા માટે ચાર્જિંગ થોભાવ્યું છે"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"નેટવર્ક લૉક થયું"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"કોઈ સિમ કાર્ડ નથી"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 25f8278..879bab5 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज हो रहा है"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • तेज़ चार्ज हो रहा है"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • धीरे चार्ज हो रहा है"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • बैटरी लाइफ़ को बढ़ाने के लिए, चार्जिंग रोक दी गई है"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"लॉक खोलने के लिए मेन्यू दबाएं."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक किया हुआ है"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"कोई सिम कार्ड नहीं है"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index 3fb8dbb..99fd8cb 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • punjenje"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • brzo punjenje"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • sporo punjenje"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje je pauzirano radi zaštite baterije"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite Izbornik da biste otključali."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nema SIM kartice"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index b4b57c6..0704545 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Töltés"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Gyors töltés"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lassú töltés"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Töltés szüneteltetve az akkumulátor védelme érdekében"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"A feloldáshoz nyomja meg a Menü gombot."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Hálózat zárolva"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nincs SIM-kártya"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index 8e58f06..ddbb54e 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Լիցքավորում"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Արագ լիցքավորում"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Դանդաղ լիցքավորում"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Լիցքավորումը դադարեցվել է մարտկոցը պաշտպանելու համար"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ապակողպելու համար սեղմեք Ընտրացանկը:"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Ցանցը կողպված է"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM քարտ չկա"</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index 20d32f1..bf1b86c 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya dengan cepat"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya dengan lambat"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pengisian daya dijeda untuk melindungi baterai"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tekan Menu untuk membuka kunci."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Jaringan terkunci"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Tidak ada kartu SIM"</string>
@@ -84,7 +85,7 @@
<string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"Perangkat dikunci oleh admin"</string>
<string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Perangkat dikunci secara manual"</string>
<string name="kg_face_not_recognized" msgid="7903950626744419160">"Tidak dikenali"</string>
- <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Untuk pakai Face Unlock, beri akses kamera di Setelan"</string>
+ <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Untuk pakai Buka dengan Wajah, beri akses kamera di Setelan"</string>
<string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Masukkan PIN SIM. Tersisa # percobaan lagi sebelum Anda harus menghubungi operator untuk membuka kunci perangkat.}other{Masukkan PIN SIM. Tersisa # percobaan lagi.}}"</string>
<string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa # percobaan lagi sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.}other{SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa # percobaan lagi sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.}}"</string>
<string name="clock_title_default" msgid="6342735240617459864">"Default"</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index fd654a3..a6f6f7d 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Í hleðslu"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hröð hleðsla"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hæg hleðsla"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hlé gert á hleðslu til að vernda rafhlöðuna"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ýttu á valmyndarhnappinn til að taka úr lás."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Net læst"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ekkert SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index cacd216..3b93495 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • In carica"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica veloce"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica lenta"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica in pausa per proteggere la batteria"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Premi Menu per sbloccare."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rete bloccata"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nessuna SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 0879ead..fbb42a6 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה מהירה"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה איטית"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • הטעינה הושהתה כדי להגן על הסוללה"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"יש ללחוץ על \'תפריט\' כדי לבטל את הנעילה."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"הרשת נעולה"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"אין כרטיס SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index e2580a5..4d3a4e0 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電中"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 急速充電中"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 低速充電中"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • バッテリーを保護するために充電を一時停止しています"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"メニューからロックを解除できます。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ネットワークがロックされました"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM カードなし"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index 7ead1a9..02d1935 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • იტენება"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • სწრაფად იტენება"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ნელა იტენება"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • დატენვა დაპაუზებულია ბატარეის დასაცავად"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"განსაბლოკად დააჭირეთ მენიუს."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ქსელი ჩაკეტილია"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM ბარ. არაა"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 0d58a67..612430c 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядталуда"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жылдам зарядталуда"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Баяу зарядталуда"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны қорғау үшін, зарядтау тоқтатылды"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ашу үшін \"Мәзір\" пернесін басыңыз."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Желі құлыптаулы"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM картасы салынбаған"</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index eaee397..f4c7bcb 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុងសាកថ្ម"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុងសាកថ្មយ៉ាងឆាប់រហ័ស"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុងសាកថ្មយឺត"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • បានផ្អាកការសាកថ្ម ដើម្បីការពារថ្ម"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ចុចម៉ឺនុយ ដើម្បីដោះសោ។"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"បណ្ដាញជាប់សោ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"គ្មានស៊ីមកាតទេ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index 8090c41..ee63b4b 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ವೇಗವಾಗಿ ಚಾರ್ಜ್ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ನಿಧಾನವಾಗಿ ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ಬ್ಯಾಟರಿಯನ್ನು ರಕ್ಷಿಸಲು ಚಾರ್ಜಿಂಗ್ ಅನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಮೆನು ಒತ್ತಿರಿ."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ನೆಟ್ವರ್ಕ್ ಲಾಕ್ ಆಗಿದೆ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index acb892b..e284edc 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 충전 중"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 고속 충전 중"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 저속 충전 중"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 배터리 보호를 위해 충전이 일시중지됨"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"잠금 해제하려면 메뉴를 누르세요."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"네트워크 잠김"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM 카드 없음"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 084be7a..61e1aac 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Кубатталууда"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Тез кубатталууда"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жай кубатталууда"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны коргоо үчүн кубаттоо тындырылды"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Кулпуну ачуу үчүн Менюну басыңыз."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Тармак кулпуланган"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM карта жок"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index 4cc86c6..d40fa7f 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກແບບດ່ວນ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກແບບຊ້າ"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ຢຸດການສາກໄວ້ຊົ່ວຄາວເພື່ອປົກປ້ອງແບັດເຕີຣີແລ້ວ"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ກົດ \"ເມນູ\" ເພື່ອປົດລັອກ."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ເຄືອຂ່າຍຖືກລັອກ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ບໍ່ມີຊິມກາດ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 1e31248..9ae5462 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Įkraunama"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Greitai įkraunama"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lėtai įkraunama"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Įkrovimas pristabdytas siekiant apsaugoti akumuliatorių"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Paspauskite meniu, jei norite atrakinti."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Tinklas užrakintas"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nėra SIM kortelės"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index c7023a6..1e59a1e 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek uzlāde"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek ātrā uzlāde"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek lēnā uzlāde"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Uzlāde apturēta, lai saudzētu akumulatoru"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lai atbloķētu, nospiediet izvēlnes ikonu."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Tīkls ir bloķēts."</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nav SIM kartes."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 625cecf..4f74412 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Се полни"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо полнење"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Бавно полнење"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Полнењето е паузирано за да се заштити батеријата"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притиснете „Мени“ за отклучување."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежата е заклучена"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нема SIM-картичка"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index da54161..f8098fb 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ചാർജ് ചെയ്യുന്നു"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • വേഗത്തിൽ ചാർജ് ചെയ്യുന്നു"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • പതുക്കെ ചാർജ് ചെയ്യുന്നു"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ബാറ്ററി പരിരക്ഷിക്കുന്നതിന്, ചാർജ് ചെയ്യൽ താൽക്കാലികമായി നിർത്തി"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"അൺലോക്കുചെയ്യാൻ മെനു അമർത്തുക."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"നെറ്റ്വർക്ക് ലോക്കുചെയ്തു"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"സിം കാർഡില്ല"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index 9cf764c..e4f8847 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Цэнэглэж байна"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Хурдан цэнэглэж байна"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Удаан цэнэглэж байна"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батарейг хамгаалахын тулд цэнэглэхийг түр зогсоосон"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Түгжээг тайлах бол цэсийг дарна уу."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сүлжээ түгжигдсэн"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM карт алга"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 635a12b..c7d4877 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज होत आहे"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • वेगाने चार्ज होत आहे"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • सावकाश चार्ज होत आहे"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • बॅटरीचे संरक्षण करण्यासाठी चार्जिंग थांबवले"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलॉक करण्यासाठी मेनू दाबा."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक केले"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"सिम कार्ड नाही"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index 06e7d86..7012145 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas dengan cepat"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas dengan perlahan"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pengecasan dijeda untuk melindungi bateri"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tekan Menu untuk membuka kunci."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rangkaian dikunci"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Tiada kad SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index ab9a6a0..7a742cb 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • အားသွင်းနေသည်"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • အမြန်အားသွင်းနေသည်"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • နှေးကွေးစွာ အားသွင်းနေသည်"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ဘက်ထရီကာကွယ်ရန် အားသွင်းခြင်း ခဏရပ်ထားသည်"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"မီနူးကို နှိပ်၍ လော့ခ်ဖွင့်ပါ။"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ကွန်ရက်ကို လော့ခ်ချထားသည်"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ဆင်းမ်ကတ် မရှိပါ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 00f52be..4e0ba44 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader raskt"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader sakte"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladingen er på pause for å beskytte batteriet"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Trykk på menyknappen for å låse opp."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Nettverket er låst"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM-kort mangler"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index aafd356..72d2c5b 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज गरिँदै"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • द्रुत गतिमा चार्ज गरिँदै छ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • मन्द गतिमा चार्ज गरिँदै"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ब्याट्री जोगाउन चार्ज गर्ने प्रक्रिया पज गरिएको छ"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लक भएको छ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM कार्ड छैन"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 8004afd..141d735 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladen"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Snel opladen"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Langzaam opladen"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladen onderbroken om de batterij te beschermen"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Druk op Menu om te ontgrendelen."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netwerk vergrendeld"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Geen simkaart"</string>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index d776e05..dc17e36 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଚାର୍ଜ ହେଉଛି"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଦ୍ରୁତ ଭାବେ ଚାର୍ଜ ହେଉଛି"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଧୀରେ ଚାର୍ଜ ହେଉଛି"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ବେଟେରୀକୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ ଚାର୍ଜିଂକୁ ବିରତ କରାଯାଇଛି"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ଅନଲକ୍ କରିବା ପାଇଁ ମେନୁକୁ ଦବାନ୍ତୁ।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ନେଟୱର୍କକୁ ଲକ୍ କରାଯାଇଛି"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"କୌଣସି SIM କାର୍ଡ ନାହିଁ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 01b3874..3e05970 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਤੇਜ਼ੀ ਨਾਲ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਹੌਲੀ-ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਬੈਟਰੀ ਦੀ ਸੁਰੱਖਿਆ ਲਈ ਚਾਰਜਿੰਗ ਨੂੰ ਰੋਕਿਆ ਗਿਆ ਹੈ"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ਅਣਲਾਕ ਕਰਨ ਲਈ \"ਮੀਨੂ\" ਦਬਾਓ।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ਨੈੱਟਵਰਕ ਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ਕੋਈ ਸਿਮ ਕਾਰਡ ਨਹੀਂ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index 70ceb3d..4d3fe58 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ładowanie"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Szybkie ładowanie"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wolne ładowanie"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wstrzymano ładowanie, aby chronić baterię"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Naciśnij Menu, aby odblokować."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Sieć zablokowana"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Brak karty SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index 8328585..f61ee04 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando rapidamente"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando lentamente"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento pausado para proteger a bateria"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pressione Menu para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sem chip"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 37d034e..e8e21fa 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar…"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar rapidamente…"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar lentamente…"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento pausado para proteger a bateria"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prima Menu para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nenhum cartão SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index 8328585..f61ee04 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando rapidamente"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando lentamente"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento pausado para proteger a bateria"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pressione Menu para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sem chip"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index de39b28..073f5ed 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă rapid"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă lent"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Încărcarea a fost întreruptă pentru a proteja bateria"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Apasă pe Meniu pentru a debloca."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rețea blocată"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Niciun card SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index c27efa3..4cd4174 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"Идет зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"Идет быстрая зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"Идет медленная зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядка приостановлена для защиты батареи"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Для разблокировки нажмите \"Меню\"."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сеть заблокирована"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нет SIM-карты."</string>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index eb742d3..6a9676f 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ආරෝපණය වෙමින්"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • වේගයෙන් ආරෝපණය වෙමින්"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • සෙමින් ආරෝපණය වෙමින්"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • බැටරිය ආරක්ෂා කිරීම සඳහා ආරෝපණය විරාම කරන ලදි"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"අගුලු හැරීමට මෙනුව ඔබන්න."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ජාලය අගුළු දමා ඇත"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM පත නැත"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index 1541076..6076198 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa rýchlo"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa pomaly"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíjanie bolo pozastavené, aby sa chránila batéria"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Odomknete stlačením tlačidla ponuky."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Sieť je zablokovaná"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Žiadna SIM karta"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index ce3af04..9269bc7 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • polnjenje"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • hitro polnjenje"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • počasno polnjenje"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Polnjenje je začasno zaustavljeno zaradi zaščite baterije"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Če želite odkleniti, pritisnite meni."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Omrežje je zaklenjeno"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ni kartice SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index 93a028a..9943955 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet me shpejtësi"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet ngadalë"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Karikimi u vendos në pauzë për të mbrojtur baterinë"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Shtyp \"Meny\" për të shkyçur."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rrjeti është i kyçur"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nuk ka kartë SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index a1004c4..01bd907 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуни се"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо се пуни"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Споро се пуни"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуњење је паузирано да би се заштитила батерија"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притисните Мени да бисте откључали."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежа је закључана"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нема SIM картице"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index c4d1489..ebba2e1 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas snabbt"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas långsamt"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddningen har pausats för att skydda batteriet"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lås upp genom att trycka på Meny."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Nätverk låst"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Inget SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index 0756944..55f4934 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji kwa kasi"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji pole pole"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Imesitisha kuchaji ili kulinda betri"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Bonyeza Menyu ili kufungua."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mtandao umefungwa"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Hakuna SIM kadi"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 962cd76..7a06971 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • சார்ஜாகிறது"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • வேகமாகச் சார்ஜாகிறது"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • மெதுவாகச் சார்ஜாகிறது"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • பேட்டரியைப் பாதுகாக்க சார்ஜிங் நிறுத்தப்பட்டுள்ளது"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"அன்லாக் செய்ய மெனுவை அழுத்தவும்."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"நெட்வொர்க் பூட்டப்பட்டது"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"சிம் கார்டு இல்லை"</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 07b12d4..20ca4b0 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ఛార్జ్ అవుతోంది"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • వేగంగా ఛార్జ్ అవుతోంది"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • నెమ్మదిగా ఛార్జ్ అవుతోంది"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • బ్యాటరీని రక్షించడానికి ఛార్జింగ్ పాజ్ చేయబడింది"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"అన్లాక్ చేయడానికి మెనూను నొక్కండి."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"నెట్వర్క్ లాక్ చేయబడింది"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM కార్డ్ లేదు"</string>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index 205075a..905dea6 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จอย่างเร็ว"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จอย่างช้าๆ"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • หยุดชาร์จชั่วคราวเพื่อยืดอายุแบตเตอรี่"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"กด \"เมนู\" เพื่อปลดล็อก"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"เครือข่ายถูกล็อก"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ไม่มีซิมการ์ด"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index fd58352..3cd1be8 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nagcha-charge"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mabilis na nagcha-charge"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mabagal na nagcha-charge"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Na-pause ang pag-charge para protektahan ang baterya"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pindutin ang Menu upang i-unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Naka-lock ang network"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Walang SIM card"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index 7d718e9..81a49cb 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj oluyor"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hızlı şarj oluyor"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Yavaş şarj oluyor"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj işlemi, pili korumak için duraklatıldı"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmak için Menü\'ye basın."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Ağ kilitli"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM kart yok"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index 9002382..0c2e8e1 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Заряджання"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Швидке заряджання"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Повільне заряджання"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Для захисту акумулятора заряджання призупинено"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Натисніть меню, щоб розблокувати."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мережу заблоковано"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Немає SIM-карти"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 944507a..24fa955 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • چارج ہو رہا ہے"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • تیزی سے چارج ہو رہا ہے"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • آہستہ چارج ہو رہا ہے"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • بیٹری کی حفاظت کرنے کے لیے چارجنگ کو روک دیا گیا"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"غیر مقفل کرنے کیلئے مینو دبائیں۔"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"نیٹ ورک مقفل ہو گیا"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"کوئی SIM کارڈ نہیں ہے"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index d3e65f5..7eab4ad 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Quvvat olmoqda"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Tezkor quvvat olmoqda"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sekin quvvat olmoqda"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Batareyaning ishlash muddatini uzaytirish uchun quvvatlash toʻxtatildi"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Qulfdan chiqarish uchun Menyu tugmasini bosing."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Tarmoq qulflangan"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM karta solinmagan"</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index bedb4f6..f52c880d 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc nhanh"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc chậm"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đã tạm dừng sạc để bảo vệ pin"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Nhấn vào Menu để mở khóa."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mạng đã bị khóa"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Không có thẻ SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index 2c7d829..c961975 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在充电"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在快速充电"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在慢速充电"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 为保护电池,系统已暂停充电"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按“菜单”即可解锁。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"网络已锁定"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"没有 SIM 卡"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index 4e8c594..eab0974 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在充電"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 快速充電中"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 慢速充電中"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 暫停充電以保護電池"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按下 [選單] 即可解鎖。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"網絡已鎖定"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"沒有 SIM 卡"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index 231b102..31fffa5 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電中"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 快速充電中"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 慢速充電中"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 暫停充電以保護電池"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按選單鍵解鎖。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"網路已鎖定"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"沒有 SIM 卡"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index eccaf13..145a8d1 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -30,7 +30,8 @@
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Iyashaja"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ishaja kaningi"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ishaja kancane"</string>
- <string name="keyguard_plugged_in_charging_limited" msgid="1657547879230699837">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ukushaja kumiswe okwesikhashana ukuvikela ibhethri"</string>
+ <!-- no translation found for keyguard_plugged_in_charging_limited (1053130519456324630) -->
+ <skip />
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Chofoza Menyu ukuvula."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Inethiwekhi ivaliwe"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Alikho ikhadi le-SIM."</string>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index da485a9..f522167 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -53,7 +53,7 @@
<string name="keyguard_plugged_in_charging_slowly"><xliff:g id="percentage">%s</xliff:g> • Charging slowly</string>
<!-- When the lock screen is showing and the phone plugged in, and the defend mode is triggered, say that charging is temporarily limited. -->
- <string name="keyguard_plugged_in_charging_limited"><xliff:g id="percentage">%s</xliff:g> • Charging paused to protect battery</string>
+ <string name="keyguard_plugged_in_charging_limited"><xliff:g id="percentage">%s</xliff:g> • Charging optimized to protect battery</string>
<!-- On the keyguard screen, when pattern lock is disabled, only tell them to press menu to unlock. This is shown in small font at the bottom. -->
<string name="keyguard_instructions_when_pattern_disabled">Press Menu to unlock.</string>
diff --git a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
index 287b3f6..f1e6eec 100644
--- a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
@@ -19,30 +19,30 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"Ponovo postavite telefon radi bržeg punjenja"</string>
- <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"Ponovo postavite telefon radi bežičnog punjenja"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Android TV će se uskoro isključiti. Pritisnite dugme da bi ostao uključen."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"U tabletu nema SIM kartice."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="7053347843877341391">"U telefonu nema SIM kartice."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"PIN kodovi se ne podudaraju"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, ovaj tablet će se resetovati, čime se brišu svi podaci korisnika."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, ovaj telefon će se resetovati, čime se brišu svi podaci korisnika."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Ovaj tablet će se resetovati, čime se brišu svi podaci."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Ovaj telefon će se resetovati, čime se brišu svi podaci."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
- <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
- <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
- <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, uklonićemo poslovni profil, čime se brišu svi podaci sa profila."</string>
- <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, uklonićemo poslovni profil, čime se brišu svi podaci sa profila."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo poslovni profil, čime se brišu svi podaci sa profila."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo poslovni profil, čime se brišu svi podaci sa profila."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate tablet pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate telefon pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
- <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Otključajte telefon za još opcija"</string>
- <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Otključajte tablet za još opcija"</string>
- <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Otključajte uređaj za još opcija"</string>
- <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Pušta se na ovom telefonu"</string>
- <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Pušta se na ovom tabletu"</string>
+ <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"Поново поставите телефон ради бржег пуњења"</string>
+ <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"Поново поставите телефон ради бежичног пуњења"</string>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Android TV ће се ускоро искључити. Притисните дугме да би остао укључен."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"Уређај ће се ускоро искључити. Притисните да би остао укључен."</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"У таблету нема SIM картице."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="7053347843877341391">"У телефону нема SIM картице."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"PIN кодови се не подударају"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, овај таблет ће се ресетовати, чиме се бришу сви подаци корисника."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, овај телефон ће се ресетовати, чиме се бришу сви подаци корисника."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Овај таблет ће се ресетовати, чиме се бришу сви подаци."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Овај телефон ће се ресетовати, чиме се бришу сви подаци."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо пословни профил, чиме се бришу сви подаци са профила."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо пословни профил, чиме се бришу сви подаци са профила."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо пословни профил, чиме се бришу сви подаци са профила."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо пословни профил, чиме се бришу сви подаци са профила."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате таблет помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате телефон помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Откључајте телефон за још опција"</string>
+ <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Откључајте таблет за још опција"</string>
+ <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Откључајте уређај за још опција"</string>
+ <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Пушта се на овом телефону"</string>
+ <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Пушта се на овом таблету"</string>
</resources>
diff --git a/packages/SystemUI/res/drawable/ic_do_not_disturb.xml b/packages/SystemUI/res/drawable/ic_do_not_disturb.xml
new file mode 100644
index 0000000..95663c0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_do_not_disturb.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM7,11h10v2L7,13z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
index 41123c8..18fcebb 100644
--- a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
+++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
@@ -16,13 +16,53 @@
* limitations under the License.
*/
-->
-<shape
+<selector
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:shape="rectangle">
- <solid android:color="?androidprv:attr/colorSurface"/>
- <size
- android:width="@dimen/keyguard_affordance_width"
- android:height="@dimen/keyguard_affordance_height"/>
- <corners android:radius="@dimen/keyguard_affordance_fixed_radius"/>
-</shape>
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+
+ <item android:state_selected="true">
+ <layer-list>
+ <item
+ android:left="3dp"
+ android:top="3dp"
+ android:right="3dp"
+ android:bottom="3dp">
+ <shape android:shape="oval">
+ <solid android:color="?androidprv:attr/colorSurface"/>
+ <size
+ android:width="@dimen/keyguard_affordance_width"
+ android:height="@dimen/keyguard_affordance_height"/>
+ </shape>
+ </item>
+
+ <item>
+ <shape android:shape="oval">
+ <stroke
+ android:color="@color/control_primary_text"
+ android:width="2dp"/>
+ <size
+ android:width="@dimen/keyguard_affordance_width"
+ android:height="@dimen/keyguard_affordance_height"/>
+ </shape>
+ </item>
+ </layer-list>
+ </item>
+
+ <item>
+ <layer-list>
+ <item
+ android:left="3dp"
+ android:top="3dp"
+ android:right="3dp"
+ android:bottom="3dp">
+ <shape android:shape="oval">
+ <solid android:color="?androidprv:attr/colorSurface"/>
+ <size
+ android:width="@dimen/keyguard_affordance_width"
+ android:height="@dimen/keyguard_affordance_height"/>
+ </shape>
+ </item>
+ </layer-list>
+ </item>
+
+</selector>
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 13c9a5e..95aefab 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -186,7 +186,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:barrierDirection="end"
app:constraint_referenced_ids="actionPrev,media_scrubbing_elapsed_time,media_progress_bar,actionNext,media_scrubbing_total_time,action0,action1,action2,action3,action4"
- app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintRight_toRightOf="@id/actionPlayPause"
/>
<!-- This barrier is used in expanded view to constrain the bottom row of actions -->
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index a5b2f80..f4b0a45 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -20,6 +20,7 @@
<com.android.systemui.statusbar.policy.RemoteInputView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/remote_input"
+ android:forceHasOverlappingRendering="false"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml
index 65983b7..efd683f 100644
--- a/packages/SystemUI/res/layout/screenshot_static.xml
+++ b/packages/SystemUI/res/layout/screenshot_static.xml
@@ -166,6 +166,7 @@
android:paddingEnd="4dp"
android:src="@drawable/ic_work_app_badge"
app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/screenshot_message_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
@@ -177,7 +178,24 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/screenshot_message_icon"
- app:layout_constraintEnd_toEndOf="parent"/>
+ app:layout_constraintEnd_toStartOf="@id/message_dismiss_button"/>
+
+ <FrameLayout
+ android:id="@+id/message_dismiss_button"
+ android:layout_width="@dimen/overlay_dismiss_button_tappable_size"
+ android:layout_height="@dimen/overlay_dismiss_button_tappable_size"
+ app:layout_constraintStart_toEndOf="@id/screenshot_message_content"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:contentDescription="@string/screenshot_dismiss_work_profile">
+ <ImageView
+ android:id="@+id/screenshot_dismiss_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="@dimen/overlay_dismiss_button_margin"
+ android:src="@drawable/overlay_cancel"/>
+ </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.android.systemui.screenshot.DraggableConstraintLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 16c615b..25a47f4 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is af"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is af"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Moenie Steur Nie is af"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\'n Outomatiese reël (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\'n Program (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\'n Outomatiese reël of program het Moenie Steur Nie aangeskakel."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hou op uitsaai"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Beskikbare toestelle vir oudio-uitsette."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitsaai werk"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Saai uit"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mense in jou omtrek met versoenbare Bluetooth-toestelle kan na die media luister wat jy uitsaai"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera en mikrofoon is af"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# kennisgewing}other{# kennisgewings}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Neem notas"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitsaai"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hou op om <xliff:g id="APP_NAME">%1$s</xliff:g> uit te saai?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"As jy <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitsaai of die uitvoer verander, sal jou huidige uitsending stop"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Saai <xliff:g id="SWITCHAPP">%1$s</xliff:g> uit"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Verander uitvoer"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE. d MMM."</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Maak <xliff:g id="APPNAME">%1$s</xliff:g> oop"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Installeer ’n kamera-app"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Die app opgestel is"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Minstens een toestel beskikbaar is"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselleer"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Draai nou om"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vou foon oop vir ’n beter selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Draai om na voorste skerm vir ’n beter selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gebruik die agterste kamera vir ’n breër foto met ’n hoër resolusie."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Hierdie skerm sal afskakel"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Voubare toestel word ontvou"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Voubare toestel word omgekeer"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 966701a..e4b5307 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -72,8 +72,7 @@
<string name="global_action_smart_lock_disabled" msgid="9097102067802412936">"Smart Lock ተሰናክሏል"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ምስል ተልኳል"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ቅጽበታዊ ገጽ እይታ በማስቀመጥ ላይ..."</string>
- <!-- no translation found for screenshot_saving_work_profile_title (5332829607308450880) -->
- <skip />
+ <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ቅጽበታዊ ገጽ እይታን ወደ የስራ መገለጫ በማስቀመጥ ላይ…"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"ቅጽበታዊ ገጽ እይታ ተቀምጧል"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"ቅጽበታዊ ገጽ ዕይታን ማስቀመጥ አልተቻለም"</string>
<string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"ቅጽበታዊ ገጽ እይታ ከመቀመጡ በፊት መሣሪያ መከፈት አለበት"</string>
@@ -394,10 +393,8 @@
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ማሳወቂያዎች በአትረብሽ ባሉበት ቆመዋል"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ምንም ማሳወቂያ የለም"</string>
- <!-- no translation found for no_unseen_notif_text (395512586119868682) -->
- <skip />
- <!-- no translation found for unlock_to_see_notif_text (7439033907167561227) -->
- <skip />
+ <string name="no_unseen_notif_text" msgid="395512586119868682">"ምንም አዲስ ማሳወቂያዎች የሉም"</string>
+ <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"የቆዩ ማሳወቂያዎችን ለማየት ይክፈቱ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው።"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"የእርስዎ ድርጅት የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
@@ -734,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ጠፍቷል"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ብሉቱዝ ጠፍቷል"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"አትረብሽ ጠፍቷል"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"አትረብሽ በአንድ ራስ-ሰር ደንብ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል።"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"አትረብሽ በአንድ መተግበሪያ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል።"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"አትረብሽ በአንድ ራስ-ሰር ደንብ ወይም መተግበሪያ በርቷል።"</string>
@@ -875,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Cast ማድረግ አቁም"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ለኦዲዮ ውጽዓት ተገኚ የሆኑ መሣሪያዎች"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"የድምጽ መጠን"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ማሰራጨት እንዴት እንደሚሠራ"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ስርጭት"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ተኳሃኝ የብሉቱዝ መሣሪያዎች ያላቸው በአቅራቢያዎ ያሉ ሰዎች እርስዎ እያሰራጩት ያሉትን ሚዲያ ማዳመጥ ይችላሉ"</string>
@@ -990,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ካሜራ እና ማይክሮፎን ጠፍተዋል"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ማሳወቂያ}one{# ማሳወቂያዎች}other{# ማሳወቂያዎች}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>፣ <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Notetaking"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"በማሰራጨት ላይ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ማሰራጨት ይቁም?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ያሰራጩ"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ውፅዓትን ይቀይሩ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ያልታወቀ"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE፣ MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ይክፈቱ"</string>
@@ -1008,6 +1004,8 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• የካሜራ መተግበሪያ ይጫኑ"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• መተግበሪያው ተዋቅሯል"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ቢያንስ አንድ መሣሪያ ይገኛል"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ይቅር"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"አሁን ገልበጥ"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ለተሻለ የራስ ፎቶ ስልክን ይዘርጉ"</string>
@@ -1018,4 +1016,6 @@
<skip />
<!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
<skip />
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index eae26f0..361cf3a 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"ميزة Wi-Fi غير مفعّلة"</string>
<string name="bt_is_off" msgid="7436344904889461591">"تم إيقاف البلوتوث."</string>
<string name="dnd_is_off" msgid="3185706903793094463">"تم إيقاف وضع \"عدم الإزعاج\""</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة تطبيق (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية أو تطبيق."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"إيقاف البث"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"الأجهزة المتاحة لإخراج الصوت"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"مستوى الصوت"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"كيفية عمل البث"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"البث"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"يمكن للأشخاص القريبين منك الذين لديهم أجهزة متوافقة تتضمّن بلوتوث الاستماع إلى الوسائط التي تبثها."</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"الكاميرا والميكروفون غير مفعّلين."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{إشعار واحد}zero{# إشعار}two{إشعاران}few{# إشعارات}many{# إشعارًا}other{# إشعار}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>، <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"تدوين الملاحظات"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"البث"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"هل تريد إيقاف بث تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>؟"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"إذا أجريت بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g> أو غيَّرت جهاز الإخراج، سيتوقَف البث الحالي."</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغيير جهاز الإخراج"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"غير معروف"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE، d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"فتح \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
@@ -1005,6 +1004,8 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• تثبيت تطبيق كاميرا"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• إعداد التطبيق"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• توفُّر جهاز واحد على الأقل"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"إلغاء"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"قلب الجهاز الآن"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"عليك فتح الهاتف لالتقاط صورة ذاتية بشكل أفضل."</string>
@@ -1015,4 +1016,6 @@
<skip />
<!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
<skip />
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 6fc82be..6c102a5 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"ৱাই-ফাই অফ অৱস্থাত আছে"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ অফ অৱস্থাত আছে"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"অসুবিধা নিদিব অফ অৱস্থাত আছে"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"অসুবিধা নিদিব-ক এটা স্বয়ংক্ৰিয় নিয়ম (<xliff:g id="ID_1">%s</xliff:g>)এ অন কৰিলে।"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"অসুবিধা নিদিব-ক কোনো এপ্ (<xliff:g id="ID_1">%s</xliff:g>)এ অন কৰিলে।"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"অসুবিধা নিদিব-ক এটা স্বয়ংক্ৰিয় নিয়ম বা এপে অন কৰিলে।"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"কাষ্ট বন্ধ কৰক"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"অডিঅ\' আউটপুটৰ বাবে উপলব্ধ ডিভাইচ।"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ভলিউম"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"সম্প্ৰচাৰ কৰাটোৱে কেনেকৈ কাম কৰে"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্ৰচাৰ"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"সমিল ব্লুটুথ ডিভাইচৰ সৈতে আপোনাৰ নিকটৱৰ্তী স্থানত থকা লোকসকলে আপুনি সম্প্ৰচাৰ কৰা মিডিয়াটো শুনিব পাৰে"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"কেমেৰা আৰু মাইক অফ হৈ আছে"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# টা জাননী}one{# টা জাননী}other{# টা জাননী}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"টোকাগ্ৰহণ"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"সম্প্ৰচাৰণ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰা বন্ধ কৰিবনে?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"যদি আপুনি <xliff:g id="SWITCHAPP">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰে অথবা আউটপুট সলনি কৰে, তেন্তে, আপোনাৰ বৰ্তমানৰ সম্প্ৰচাৰ বন্ধ হৈ যাব"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্ৰচাৰ কৰক"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট সলনি কৰক"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজ্ঞাত"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> খোলক"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• এটা কেমেৰা এপ্ ইনষ্টল কৰক"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• এপ্টো ছেট আপ কৰা হৈছে"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• অতি কমেও এটা ডিভাইচ উপলব্ধ"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল কৰক"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এতিয়াই লুটিয়াই দিয়ক"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"উন্নত ছেল্ফিৰ বাবে ফ’নটো আনফ’ল্ড কৰক"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"উন্নত ছেল্ফিৰ বাবে সন্মুখৰ ডিছপ্লে’ লুটিয়াই দিবনে?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"অধিক ৰিজ’লিউশ্বনৰ বহল ফট’ৰ বাবে পিছফালে থকা কেমেৰাটো ব্যৱহাৰ কৰক।"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ই স্ক্ৰীনখন অফ হ’ব"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"জপাব পৰা ডিভাইচৰ জাপ খুলি থকা হৈছে"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"জপাব পৰা ডিভাইচৰ ওলোটাই থকা হৈছে"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index e4e031a..d2529a2 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi deaktivdir"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth deaktivdir"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"\"Narahat Etməyin\" deaktivdir"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"Narahat etməyin\" rejimi (<xliff:g id="ID_1">%s</xliff:g>) avtomatik qaydası tərəfindən aktiv edildi."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"Narahat etməyin\" rejimi (<xliff:g id="ID_1">%s</xliff:g>) tətbiqi tərəfindən aktiv edildi."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"Narahat etməyin\" rejimi avtomatik qayda və ya tətbiq tərəfindən aktiv edildi."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayımı dayandırın"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio çıxış üçün əlçatan cihazlar."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Səs"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayım necə işləyir"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Yayım"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Uyğun Bluetooth cihazları olan yaxınlığınızdakı insanlar yayımladığınız medianı dinləyə bilər"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera və mikrofon deaktivdir"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildiriş}other{# bildiriş}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Qeyd tutma"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayım"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinin yayımlanması dayandırılsın?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlasanız və ya nəticəni dəyişsəniz, cari yayımınız dayandırılacaq"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlayın"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Nəticəni dəyişdirin"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Naməlum"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"HHH, AAA g"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ss:dd"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> tətbiqini açın"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera tətbiqini quraşdırın"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Tətbiq ayarlanmalıdır"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ən azı bir cihaz əlçatandır"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ləğv edin"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"İndi fırladın"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha yaxşı selfi üçün telefonu açın"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Daha yaxşı selfi üçün ön displeyə çevrilsin?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Daha yüksək ayırdetmə dəqiqliyi ilə daha geniş şəkil üçün arxaya baxan kameradan istifadə edin."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran deaktiv ediləcək"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Qatlana bilən cihaz açılır"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Qatlana bilən cihaz fırladılır"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn-land/strings.xml b/packages/SystemUI/res/values-b+sr+Latn-land/strings.xml
index b956edb..992fe1c 100644
--- a/packages/SystemUI/res/values-b+sr+Latn-land/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn-land/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="toast_rotation_locked" msgid="4914046305911646988">"Ekran je sada zaključan u vertikalnom položaju."</string>
+ <string name="toast_rotation_locked" msgid="4914046305911646988">"Екран је сада закључан у вертикалном положају."</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn-ldrtl/strings.xml b/packages/SystemUI/res/values-b+sr+Latn-ldrtl/strings.xml
index 8e5ecf9..f4106f1 100644
--- a/packages/SystemUI/res/values-b+sr+Latn-ldrtl/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn-ldrtl/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Prevucite ulevo da biste brzo promenili aplikacije"</string>
+ <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Превуците улево да бисте брзо променили апликације"</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index bd964f95..f3c3de3 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -19,998 +19,1001 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4811759950673118541">"UI sistema"</string>
- <string name="battery_low_title" msgid="5319680173344341779">"Želite li da uključite Uštedu baterije?"</string>
- <string name="battery_low_description" msgid="3282977755476423966">"Preostali nivo napunjenosti baterije je <xliff:g id="PERCENTAGE">%s</xliff:g>. Ušteda baterije uključuje Tamnu temu, ograničava aktivnosti u pozadini i odlaže obaveštenja."</string>
- <string name="battery_low_intro" msgid="5148725009653088790">"Ušteda baterije uključuje Tamnu temu, ograničava aktivnosti u pozadini i odlaže obaveštenja."</string>
- <string name="battery_low_percent_format" msgid="4276661262843170964">"Još <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
- <string name="invalid_charger_title" msgid="938685362320735167">"Punjenje preko USB-a nije uspelo"</string>
- <string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili uz uređaj"</string>
- <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Želite da uključite Uštedu baterije?"</string>
- <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"O Uštedi baterije"</string>
- <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Uključi"</string>
- <string name="battery_saver_start_action" msgid="8353766979886287140">"Uključi"</string>
- <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, hvala"</string>
- <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatsko rotiranje ekrana"</string>
- <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Dozvoljavate da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
- <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Želite li da dozvolite da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nOva aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string>
- <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Dozvoljavate da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
- <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili uređaj <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
- <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ova aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja. Ako koristite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> sa ovim uređajem, možda nećete čuti pozive, obaveštenja i alarme."</string>
- <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ako koristite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> sa ovim uređajem, možda nećete čuti pozive, obaveštenja i alarme."</string>
- <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Dozvoljavate da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
- <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Želite da otvorite <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
- <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> radi rukovanja uređajem <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nOva aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string>
- <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili uređaj <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Instalirane aplikacije ne funkcionišu sa ovim USB pomoćnim uređajem. Saznajte više o njemu na adresi <xliff:g id="URL">%1$s</xliff:g>"</string>
- <string name="title_usb_accessory" msgid="1236358027511638648">"USB pomoćni uređaj"</string>
- <string name="label_view" msgid="6815442985276363364">"Prikaži"</string>
- <string name="always_use_device" msgid="210535878779644679">"Uvek otvaraj aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> kada je uređaj <xliff:g id="USB_DEVICE">%2$s</xliff:g> povezan"</string>
- <string name="always_use_accessory" msgid="1977225429341838444">"Uvek otvaraj aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> kada je uređaj <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> povezan"</string>
- <string name="usb_debugging_title" msgid="8274884945238642726">"Želite li da dozvolite otklanjanje USB grešaka?"</string>
- <string name="usb_debugging_message" msgid="5794616114463921773">"Digitalni otisak RSA ključa ovog računara je:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
- <string name="usb_debugging_always" msgid="4003121804294739548">"Uvek dozvoli sa ovog računara"</string>
- <string name="usb_debugging_allow" msgid="1722643858015321328">"Dozvoli"</string>
- <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Otklanjanje grešaka na USB-u nije dozvoljeno"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi otklanjanje grešaka na USB-u. Da biste koristili ovu funkciju, prebacite na primarnog korisnika."</string>
- <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Da li želite da promenite jezik sistema na <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
- <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Drugi uređaj je zatražio promenu jezika sistema"</string>
- <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Promeni jezik"</string>
- <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Zadrži aktuelni jezik"</string>
- <string name="wifi_debugging_title" msgid="7300007687492186076">"Želite da dozvolite bežično otklanjanje grešaka na ovoj mreži?"</string>
- <string name="wifi_debugging_message" msgid="5461204211731802995">"Naziv mreže (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi adresa (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
- <string name="wifi_debugging_always" msgid="2968383799517975155">"Uvek dozvoli na ovoj mreži"</string>
- <string name="wifi_debugging_allow" msgid="4573224609684957886">"Dozvoli"</string>
- <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Bežično otklanjanje grešaka nije dozvoljeno"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi bežično otklanjanje grešaka. Da biste koristili ovu funkciju, pređite na primarnog korisnika."</string>
- <string name="usb_contaminant_title" msgid="894052515034594113">"USB port je onemogućen"</string>
- <string name="usb_contaminant_message" msgid="7730476585174719805">"Da bi se uređaj zaštitio od tečnosti ili nečistoće, USB port je onemogućen i neće otkrivati dodatnu opremu.\n\nObavestićemo vas kada ponovo budete mogli da koristite USB port."</string>
- <string name="usb_port_enabled" msgid="531823867664717018">"USB port je omogućen radi otkrivanja punjača i dodatne opreme"</string>
- <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Omogući USB"</string>
- <string name="learn_more" msgid="4690632085667273811">"Saznajte više"</string>
- <string name="global_action_screenshot" msgid="2760267567509131654">"Snimak ekrana"</string>
- <string name="global_action_smart_lock_disabled" msgid="9097102067802412936">"Smart Lock je onemogućen"</string>
- <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslao/la sliku"</string>
- <string name="screenshot_saving_title" msgid="2298349784913287333">"Čuvanje snimka ekrana..."</string>
- <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Snimak ekrana se čuva na poslovnom profilu…"</string>
- <string name="screenshot_saved_title" msgid="8893267638659083153">"Snimak ekrana je sačuvan"</string>
- <string name="screenshot_failed_title" msgid="3259148215671936891">"Čuvanje snimka ekrana nije uspelo"</string>
- <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"Uređaj mora da bude otključan da bi snimak ekrana mogao da se sačuva"</string>
- <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probajte da ponovo napravite snimak ekrana"</string>
- <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Čuvanje snimka ekrana nije uspelo"</string>
- <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana"</string>
- <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT administrator blokira pravljenje snimaka ekrana"</string>
- <string name="screenshot_edit_label" msgid="8754981973544133050">"Izmeni"</string>
- <string name="screenshot_edit_description" msgid="3333092254706788906">"Izmenite snimak ekrana"</string>
- <string name="screenshot_share_description" msgid="2861628935812656612">"Delite snimak ekrana"</string>
- <string name="screenshot_scroll_label" msgid="2930198809899329367">"Snimite još"</string>
- <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacite snimak ekrana"</string>
- <string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimka ekrana"</string>
- <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Gornja ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
- <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donja ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
- <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Leva ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
- <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desna ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
- <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string>
- <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string>
- <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
- <string name="screenrecord_start_label" msgid="1750350278888217473">"Želite da započnete snimanje?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"Tokom snimanja Android sistem može da snimi osetljive informacije koje su vidljive na ekranu ili koje se puštaju na uređaju. To obuhvata lozinke, informacije o plaćanju, slike, poruke i zvuk."</string>
- <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"Snimaj ceo ekran"</string>
- <string name="screenrecord_option_single_app" msgid="5954863081500035825">"Snimaj jednu aplikaciju"</string>
- <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju dok snimate. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
- <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"Kada snimate aplikaciju, Android ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
- <string name="screenrecord_start_recording" msgid="348286842544768740">"Započni snimanje"</string>
- <string name="screenrecord_audio_label" msgid="6183558856175159629">"Snimaj zvuk"</string>
- <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk uređaja"</string>
- <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk sa uređaja, na primer, muzika, pozivi i melodije zvona"</string>
- <string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
- <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Zvuk uređaja i mikrofon"</string>
- <string name="screenrecord_start" msgid="330991441575775004">"Pokreni"</string>
- <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Snima se ekran"</string>
- <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Snimaju se ekran i zvuk"</string>
- <string name="screenrecord_taps_label" msgid="1595690528298857649">"Prikazuj dodire na ekranu"</string>
- <string name="screenrecord_stop_label" msgid="72699670052087989">"Zaustavi"</string>
- <string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"Snimak ekrana je sačuvan"</string>
- <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da biste pregledali"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Došlo je do problema pri brisanju snimka ekrana"</string>
- <string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
- <string name="accessibility_back" msgid="6530104400086152611">"Nazad"</string>
- <string name="accessibility_home" msgid="5430449841237966217">"Početna"</string>
- <string name="accessibility_menu" msgid="2701163794470513040">"Meni"</string>
- <string name="accessibility_accessibility_button" msgid="4089042473497107709">"Pristupačnost"</string>
- <string name="accessibility_rotate_button" msgid="1238584767612362586">"Rotirajte ekran"</string>
- <string name="accessibility_recent" msgid="901641734769533575">"Pregled"</string>
- <string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
- <string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
- <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
- <string name="accessibility_wallet_button" msgid="1458258783460555507">"Novčanik"</string>
- <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skener QR koda"</string>
- <string name="accessibility_unlock_button" msgid="3613812140816244310">"Otključano"</string>
- <string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
- <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
- <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
- <string name="cancel" msgid="1089011503403416730">"Otkaži"</string>
- <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string>
- <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probaj ponovo"</string>
- <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Dodirnite da biste otkazali potvrdu identiteta"</string>
- <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"Probajte ponovo"</string>
- <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"Traži se vaše lice"</string>
- <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je potvrđeno"</string>
- <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
- <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da biste završili"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano je licem. Pritisnite ikonu otključavanja za nastavak"</string>
- <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano je licem. Pritisnite da biste nastavili."</string>
- <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
- <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu otključavanja za nastavak."</string>
- <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
- <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
- <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite šablon"</string>
- <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Koristite lozinku"</string>
- <string name="biometric_dialog_wrong_pin" msgid="1878539073972762803">"Pogrešan PIN"</string>
- <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Pogrešan šablon"</string>
- <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Pogrešna lozinka"</string>
- <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Previše netačnih pokušaja.\n Probajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
- <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Probajte ponovo. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. pokušaj od <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string>
- <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Podaci će se izbrisati"</string>
- <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ako unesete netačan šablon pri sledećem pokušaju, izbrisaćemo podatke sa ovog uređaja."</string>
- <string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"Ako unesete netačan PIN pri sledećem pokušaju, izbrisaćemo podatke sa ovog uređaja."</string>
- <string name="biometric_dialog_last_password_attempt_before_wipe_device" msgid="2363778585575998317">"Ako unesete netačnu lozinku pri sledećem pokušaju, izbrisaćemo podatke sa ovog uređaja."</string>
- <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"Ako unesete netačan šablon pri sledećem pokušaju, izbrisaćemo ovog korisnika."</string>
- <string name="biometric_dialog_last_pin_attempt_before_wipe_user" msgid="4159878829962411168">"Ako unesete netačan PIN pri sledećem pokušaju, izbrisaćemo ovog korisnika."</string>
- <string name="biometric_dialog_last_password_attempt_before_wipe_user" msgid="4695682515465063885">"Ako unesete netačnu lozinku pri sledećem pokušaju, izbrisaćemo ovog korisnika."</string>
- <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ako unesete netačan šablon pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
- <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ako unesete netačan PIN pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
- <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ako unesete netačnu lozinku pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
- <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dodirnite senzor za otisak prsta"</string>
- <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona otiska prsta"</string>
- <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Lice nije prepoznato. Koristite otisak prsta."</string>
+ <string name="app_label" msgid="4811759950673118541">"UI система"</string>
+ <string name="battery_low_title" msgid="5319680173344341779">"Желите ли да укључите Уштеду батерије?"</string>
+ <string name="battery_low_description" msgid="3282977755476423966">"Преостали ниво напуњености батерије је <xliff:g id="PERCENTAGE">%s</xliff:g>. Уштеда батерије укључује Тамну тему, ограничава активности у позадини и одлаже обавештења."</string>
+ <string name="battery_low_intro" msgid="5148725009653088790">"Уштеда батерије укључује Тамну тему, ограничава активности у позадини и одлаже обавештења."</string>
+ <string name="battery_low_percent_format" msgid="4276661262843170964">"Још <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
+ <string name="invalid_charger_title" msgid="938685362320735167">"Пуњење преко USB-а није успело"</string>
+ <string name="invalid_charger_text" msgid="2339310107232691577">"Користите пуњач који сте добили уз уређај"</string>
+ <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Желите да укључите Уштеду батерије?"</string>
+ <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"О Уштеди батерије"</string>
+ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Укључи"</string>
+ <string name="battery_saver_start_action" msgid="8353766979886287140">"Укључи"</string>
+ <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Не, хвала"</string>
+ <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аутоматско ротирање екрана"</string>
+ <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Дозвољавате да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Желите ли да дозволите да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nОва апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Дозвољавате да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили уређај <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Ова апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја. Ако користите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> са овим уређајем, можда нећете чути позиве, обавештења и аларме."</string>
+ <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ако користите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> са овим уређајем, можда нећете чути позиве, обавештења и аларме."</string>
+ <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Дозвољавате да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
+ <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Желите да отворите <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> ради руковања уређајем <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nОва апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string>
+ <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили уређај <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
+ <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Инсталиране апликације не функционишу са овим USB помоћним уређајем. Сазнајте више о њему на адреси <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <string name="title_usb_accessory" msgid="1236358027511638648">"USB помоћни уређај"</string>
+ <string name="label_view" msgid="6815442985276363364">"Прикажи"</string>
+ <string name="always_use_device" msgid="210535878779644679">"Увек отварај апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> када је уређај <xliff:g id="USB_DEVICE">%2$s</xliff:g> повезан"</string>
+ <string name="always_use_accessory" msgid="1977225429341838444">"Увек отварај апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> када је уређај <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> повезан"</string>
+ <string name="usb_debugging_title" msgid="8274884945238642726">"Желите ли да дозволите отклањање USB грешака?"</string>
+ <string name="usb_debugging_message" msgid="5794616114463921773">"Дигитални отисак RSA кључа овог рачунара је:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+ <string name="usb_debugging_always" msgid="4003121804294739548">"Увек дозволи са овог рачунара"</string>
+ <string name="usb_debugging_allow" msgid="1722643858015321328">"Дозволи"</string>
+ <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Отклањање грешака на USB-у није дозвољено"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Корисник који је тренутно пријављен на овај уређај не може да укључи отклањање грешака на USB-у. Да бисте користили ову функцију, пребаците на примарног корисника."</string>
+ <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Да ли желите да промените језик система на <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
+ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Други уређај је затражио промену језика система"</string>
+ <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Промени језик"</string>
+ <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Задржи актуелни језик"</string>
+ <string name="wifi_debugging_title" msgid="7300007687492186076">"Желите да дозволите бежично отклањање грешака на овој мрежи?"</string>
+ <string name="wifi_debugging_message" msgid="5461204211731802995">"Назив мреже (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi адреса (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
+ <string name="wifi_debugging_always" msgid="2968383799517975155">"Увек дозволи на овој мрежи"</string>
+ <string name="wifi_debugging_allow" msgid="4573224609684957886">"Дозволи"</string>
+ <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Бежично отклањање грешака није дозвољено"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Корисник који је тренутно пријављен на овај уређај не може да укључи бежично отклањање грешака. Да бисте користили ову функцију, пређите на примарног корисника."</string>
+ <string name="usb_contaminant_title" msgid="894052515034594113">"USB порт је онемогућен"</string>
+ <string name="usb_contaminant_message" msgid="7730476585174719805">"Да би се уређај заштитио од течности или нечистоће, USB порт је онемогућен и неће откривати додатну опрему.\n\nОбавестићемо вас када поново будете могли да користите USB порт."</string>
+ <string name="usb_port_enabled" msgid="531823867664717018">"USB порт је омогућен ради откривања пуњача и додатне опреме"</string>
+ <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Омогући USB"</string>
+ <string name="learn_more" msgid="4690632085667273811">"Сазнајте више"</string>
+ <string name="global_action_screenshot" msgid="2760267567509131654">"Снимак екрана"</string>
+ <string name="global_action_smart_lock_disabled" msgid="9097102067802412936">"Smart Lock је онемогућен"</string>
+ <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"је послао/ла слику"</string>
+ <string name="screenshot_saving_title" msgid="2298349784913287333">"Чување снимка екрана..."</string>
+ <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Снимак екрана се чува на пословном профилу…"</string>
+ <string name="screenshot_saved_title" msgid="8893267638659083153">"Снимак екрана је сачуван"</string>
+ <string name="screenshot_failed_title" msgid="3259148215671936891">"Чување снимка екрана није успело"</string>
+ <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"Уређај мора да буде откључан да би снимак екрана могао да се сачува"</string>
+ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Пробајте да поново направите снимак екрана"</string>
+ <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Чување снимка екрана није успело"</string>
+ <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Апликација или организација не дозвољавају прављење снимака екрана"</string>
+ <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ИТ администратор блокира прављење снимака екрана"</string>
+ <string name="screenshot_edit_label" msgid="8754981973544133050">"Измени"</string>
+ <string name="screenshot_edit_description" msgid="3333092254706788906">"Измените снимак екрана"</string>
+ <string name="screenshot_share_description" msgid="2861628935812656612">"Делите снимак екрана"</string>
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Снимите још"</string>
+ <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Одбаците снимак екрана"</string>
+ <string name="screenshot_preview_description" msgid="7606510140714080474">"Преглед снимка екрана"</string>
+ <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Горња ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
+ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Доња ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
+ <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лева ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
+ <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Десна ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
+ <string name="screenrecord_name" msgid="2596401223859996572">"Снимач екрана"</string>
+ <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
+ <string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
+ <string name="screenrecord_start_label" msgid="1750350278888217473">"Желите да започнете снимање?"</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"Током снимања Android систем може да сними осетљиве информације које су видљиве на екрану или које се пуштају на уређају. То обухвата лозинке, информације о плаћању, слике, поруке и звук."</string>
+ <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"Снимај цео екран"</string>
+ <string name="screenrecord_option_single_app" msgid="5954863081500035825">"Снимај једну апликацију"</string>
+ <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају док снимате. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
+ <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"Када снимате апликацију, Android има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
+ <string name="screenrecord_start_recording" msgid="348286842544768740">"Започни снимање"</string>
+ <string name="screenrecord_audio_label" msgid="6183558856175159629">"Снимај звук"</string>
+ <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Звук уређаја"</string>
+ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Звук са уређаја, на пример, музика, позиви и мелодије звона"</string>
+ <string name="screenrecord_mic_label" msgid="2111264835791332350">"Микрофон"</string>
+ <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Звук уређаја и микрофон"</string>
+ <string name="screenrecord_start" msgid="330991441575775004">"Покрени"</string>
+ <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Снима се екран"</string>
+ <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Снимају се екран и звук"</string>
+ <string name="screenrecord_taps_label" msgid="1595690528298857649">"Приказуј додире на екрану"</string>
+ <string name="screenrecord_stop_label" msgid="72699670052087989">"Заустави"</string>
+ <string name="screenrecord_share_label" msgid="5025590804030086930">"Дели"</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"Снимак екрана је сачуван"</string>
+ <string name="screenrecord_save_text" msgid="3008973099800840163">"Додирните да бисте прегледали"</string>
+ <string name="screenrecord_delete_error" msgid="2870506119743013588">"Дошло је до проблема при брисању снимка екрана"</string>
+ <string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при покретању снимања екрана"</string>
+ <string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
+ <string name="accessibility_home" msgid="5430449841237966217">"Почетна"</string>
+ <string name="accessibility_menu" msgid="2701163794470513040">"Мени"</string>
+ <string name="accessibility_accessibility_button" msgid="4089042473497107709">"Приступачност"</string>
+ <string name="accessibility_rotate_button" msgid="1238584767612362586">"Ротирајте екран"</string>
+ <string name="accessibility_recent" msgid="901641734769533575">"Преглед"</string>
+ <string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
+ <string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
+ <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Гласовна помоћ"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Новчаник"</string>
+ <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Скенер QR кода"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"Откључано"</string>
+ <string name="accessibility_lock_icon" msgid="661492842417875775">"Уређај је закључан"</string>
+ <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лица"</string>
+ <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Пошаљи"</string>
+ <string name="cancel" msgid="1089011503403416730">"Откажи"</string>
+ <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string>
+ <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Пробај поново"</string>
+ <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Додирните да бисте отказали потврду идентитета"</string>
+ <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"Пробајте поново"</string>
+ <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"Тражи се ваше лице"</string>
+ <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лице је потврђено"</string>
+ <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврђено"</string>
+ <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Додирните Потврди да бисте завршили"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Откључано је лицем. Притисните икону откључавања за наставак"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Откључано је лицем. Притисните да бисте наставили."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лице је препознато. Притисните да бисте наставили."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лице препознато. Притисните икону откључавања за наставак."</string>
+ <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Идентитет је потврђен"</string>
+ <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користите PIN"</string>
+ <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користите шаблон"</string>
+ <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Користите лозинку"</string>
+ <string name="biometric_dialog_wrong_pin" msgid="1878539073972762803">"Погрешан PIN"</string>
+ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Погрешан шаблон"</string>
+ <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Погрешна лозинка"</string>
+ <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Превише нетачних покушаја.\n Пробајте поново за <xliff:g id="NUMBER">%d</xliff:g> сек."</string>
+ <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Пробајте поново. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. покушај од <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string>
+ <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Подаци ће се избрисати"</string>
+ <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ако унесете нетачан шаблон при следећем покушају, избрисаћемо податке са овог уређаја."</string>
+ <string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"Ако унесете нетачан PIN при следећем покушају, избрисаћемо податке са овог уређаја."</string>
+ <string name="biometric_dialog_last_password_attempt_before_wipe_device" msgid="2363778585575998317">"Ако унесете нетачну лозинку при следећем покушају, избрисаћемо податке са овог уређаја."</string>
+ <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"Ако унесете нетачан шаблон при следећем покушају, избрисаћемо овог корисника."</string>
+ <string name="biometric_dialog_last_pin_attempt_before_wipe_user" msgid="4159878829962411168">"Ако унесете нетачан PIN при следећем покушају, избрисаћемо овог корисника."</string>
+ <string name="biometric_dialog_last_password_attempt_before_wipe_user" msgid="4695682515465063885">"Ако унесете нетачну лозинку при следећем покушају, избрисаћемо овог корисника."</string>
+ <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ако унесете нетачан шаблон при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
+ <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ако унесете нетачан PIN при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
+ <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ако унесете нетачну лозинку при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
+ <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Додирните сензор за отисак прста"</string>
+ <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Икона отиска прста"</string>
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Лице није препознато. Користите отисак прста."</string>
<!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
<skip />
- <string name="keyguard_face_failed" msgid="9044619102286917151">"Lice nije prepoznato"</string>
- <string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Koristite otisak prsta"</string>
- <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"Otključavanje licem nije dostupno"</string>
- <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth je priključen."</string>
- <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procenat napunjenosti baterije nije poznat."</string>
- <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezani ste sa <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
- <string name="accessibility_cast_name" msgid="7344437925388773685">"Povezani smo sa uređajem <xliff:g id="CAST">%s</xliff:g>."</string>
- <string name="accessibility_not_connected" msgid="4061305616351042142">"Nije povezano."</string>
- <string name="data_connection_roaming" msgid="375650836665414797">"Roming"</string>
- <string name="cell_data_off" msgid="4886198950247099526">"Isključeno"</string>
- <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Režim rada u avionu."</string>
- <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN je uključen."</string>
- <string name="accessibility_battery_level" msgid="5143715405241138822">"Baterija je na <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Baterija je na <xliff:g id="PERCENTAGE">%1$d</xliff:g> posto, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> posto."</string>
- <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Baterija je na <xliff:g id="PERCENTAGE">%d</xliff:g> posto, punjenje je pauzirano da bi se zaštitila baterija."</string>
- <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Baterija je na <xliff:g id="PERCENTAGE">%1$d</xliff:g> posto, <xliff:g id="TIME">%2$s</xliff:g>, punjenje je pauzirano da bi se zaštitila baterija."</string>
- <string name="accessibility_overflow_action" msgid="8555835828182509104">"Pogledajte sva obaveštenja"</string>
- <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter je omogućen."</string>
- <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibracija zvona."</string>
- <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Nečujno zvono."</string>
+ <string name="keyguard_face_failed" msgid="9044619102286917151">"Лице није препознато"</string>
+ <string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Користите отисак прста"</string>
+ <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"Откључавање лицем није доступно"</string>
+ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth је прикључен."</string>
+ <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Проценат напуњености батерије није познат."</string>
+ <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Повезани сте са <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
+ <string name="accessibility_cast_name" msgid="7344437925388773685">"Повезани смо са уређајем <xliff:g id="CAST">%s</xliff:g>."</string>
+ <string name="accessibility_not_connected" msgid="4061305616351042142">"Није повезано."</string>
+ <string name="data_connection_roaming" msgid="375650836665414797">"Роминг"</string>
+ <string name="cell_data_off" msgid="4886198950247099526">"Искључено"</string>
+ <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Режим рада у авиону."</string>
+ <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN је укључен."</string>
+ <string name="accessibility_battery_level" msgid="5143715405241138822">"Батерија је на <xliff:g id="NUMBER">%d</xliff:g> посто."</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Батерија је на <xliff:g id="PERCENTAGE">%1$d</xliff:g> посто, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батерија се пуни, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> посто."</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Батерија је на <xliff:g id="PERCENTAGE">%d</xliff:g> посто, пуњење је паузирано да би се заштитила батерија."</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Батерија је на <xliff:g id="PERCENTAGE">%1$d</xliff:g> посто, <xliff:g id="TIME">%2$s</xliff:g>, пуњење је паузирано да би се заштитила батерија."</string>
+ <string name="accessibility_overflow_action" msgid="8555835828182509104">"Погледајте сва обавештења"</string>
+ <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter је омогућен."</string>
+ <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Вибрација звона."</string>
+ <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Нечујно звоно."</string>
<!-- no translation found for accessibility_casting (8708751252897282313) -->
<skip />
- <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Prozor sa obaveštenjima."</string>
- <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brza podešavanja."</string>
- <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključan ekran."</string>
- <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan ekran za posao"</string>
- <string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
- <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
- <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
- <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne uznemiravaj."</string>
+ <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Прозор са обавештењима."</string>
+ <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Брза подешавања."</string>
+ <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Закључан екран."</string>
+ <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Закључан екран за посао"</string>
+ <string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
+ <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"потпуна тишина"</string>
+ <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"само аларми"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не узнемиравај."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
- <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth je uključen."</string>
- <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm je podešen za <xliff:g id="TIME">%s</xliff:g>."</string>
- <string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"Više vremena."</string>
- <string name="accessibility_quick_settings_less_time" msgid="9110364286464977870">"Manje vremena."</string>
- <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Prebacivanje ekrana je zaustavljeno."</string>
- <string name="accessibility_brightness" msgid="5391187016177823721">"Osvetljenost ekrana"</string>
- <string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"Mobilni podaci su pauzirani"</string>
- <string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"Podaci su pauzirani"</string>
- <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"Dostigli se ograničenje za podatke koje ste podesili. Više ne koristite mobilne podatke.\n\nAko nastavite, možda će važiti tarife za potrošnju podataka."</string>
- <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"Nastavi"</string>
- <string name="accessibility_location_active" msgid="2845747916764660369">"Ima aktivnih zahteva za lokaciju"</string>
- <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Senzori su isključeni"</string>
- <string name="accessibility_clear_all" msgid="970525598287244592">"Obriši sva obaveštenja."</string>
- <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"i još <xliff:g id="NUMBER">%s</xliff:g>"</string>
- <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Unutra je još # obaveštenje.}one{Unutra je još # obaveštenje.}few{Unutra su još # obaveštenja.}other{Unutra je još # obaveštenja.}}"</string>
- <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekran je zaključan u horizontalnom položaju."</string>
- <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekran je zaključan u vertikalnom položaju."</string>
- <string name="dessert_case" msgid="9104973640704357717">"Vitrina sa poslasticama"</string>
- <string name="start_dreams" msgid="9131802557946276718">"Čuvar ekrana"</string>
- <string name="ethernet_label" msgid="2203544727007463351">"Eternet"</string>
- <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne uznemiravaj"</string>
+ <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth је укључен."</string>
+ <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Аларм је подешен за <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"Више времена."</string>
+ <string name="accessibility_quick_settings_less_time" msgid="9110364286464977870">"Мање времена."</string>
+ <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Пребацивање екрана је заустављено."</string>
+ <string name="accessibility_brightness" msgid="5391187016177823721">"Осветљеност екрана"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"Мобилни подаци су паузирани"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"Подаци су паузирани"</string>
+ <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"Достигли се ограничење за податке које сте подесили. Више не користите мобилне податке.\n\nАко наставите, можда ће важити тарифе за потрошњу података."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"Настави"</string>
+ <string name="accessibility_location_active" msgid="2845747916764660369">"Има активних захтева за локацију"</string>
+ <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Сензори су искључени"</string>
+ <string name="accessibility_clear_all" msgid="970525598287244592">"Обриши сва обавештења."</string>
+ <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"и још <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Унутра је још # обавештење.}one{Унутра је још # обавештење.}few{Унутра су још # обавештења.}other{Унутра је још # обавештења.}}"</string>
+ <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Екран је закључан у хоризонталном положају."</string>
+ <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Екран је закључан у вертикалном положају."</string>
+ <string name="dessert_case" msgid="9104973640704357717">"Витрина са посластицама"</string>
+ <string name="start_dreams" msgid="9131802557946276718">"Чувар екрана"</string>
+ <string name="ethernet_label" msgid="2203544727007463351">"Етернет"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не узнемиравај"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
- <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nije dostupan nijedan upareni uređaj"</string>
- <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
- <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
- <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string>
- <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Unos"</string>
- <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Slušni aparati"</string>
- <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključuje se..."</string>
- <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatska rotacija"</string>
- <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
- <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
- <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Čuvar ekrana"</string>
- <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup kameri"</string>
- <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pristup mikrofonu"</string>
- <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupno"</string>
- <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Blokirano"</string>
- <string name="quick_settings_media_device_label" msgid="8034019242363789941">"Medijski uređaj"</string>
- <string name="quick_settings_user_title" msgid="8673045967216204537">"Korisnik"</string>
+ <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Није доступан ниједан упарени уређај"</string>
+ <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
+ <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string>
+ <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалице"</string>
+ <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Унос"</string>
+ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Слушни апарати"</string>
+ <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Укључује се..."</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аутоматска ротација"</string>
+ <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аутоматско ротирање екрана"</string>
+ <string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
+ <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Чувар екрана"</string>
+ <string name="quick_settings_camera_label" msgid="5612076679385269339">"Приступ камери"</string>
+ <string name="quick_settings_mic_label" msgid="8392773746295266375">"Приступ микрофону"</string>
+ <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Доступно"</string>
+ <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Блокирано"</string>
+ <string name="quick_settings_media_device_label" msgid="8034019242363789941">"Медијски уређај"</string>
+ <string name="quick_settings_user_title" msgid="8673045967216204537">"Корисник"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"WiFi"</string>
- <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
- <string name="quick_settings_networks_available" msgid="1875138606855420438">"Mreže su dostupne"</string>
- <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Mreže nisu dostupne"</string>
- <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Nije dostupna nijedna WiFi mreža"</string>
- <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Uključuje se..."</string>
- <string name="quick_settings_cast_title" msgid="2279220930629235211">"Prebacivanje ekrana"</string>
- <string name="quick_settings_casting" msgid="1435880708719268055">"Prebacivanje"</string>
- <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Neimenovani uređaj"</string>
- <string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Nije dostupan nijedan uređaj"</string>
- <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"WiFi nije povezan"</string>
- <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Osvetljenost"</string>
- <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija boja"</string>
- <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekcija boja"</string>
- <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljajte korisnicima"</string>
- <string name="quick_settings_done" msgid="2163641301648855793">"Gotovo"</string>
- <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zatvori"</string>
- <string name="quick_settings_connected" msgid="3873605509184830379">"Povezan"</string>
- <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Povezano, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="quick_settings_connecting" msgid="2381969772953268809">"Povezuje se..."</string>
- <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
- <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Uključuje se..."</string>
- <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ušteda podataka je uključena"</string>
- <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# uređaj}one{# uređaj}few{# uređaja}other{# uređaja}}"</string>
- <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampa"</string>
- <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Koristi se kamera"</string>
- <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobilni podaci"</string>
- <string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Potrošnja podataka"</string>
- <string name="quick_settings_cellular_detail_remaining_data" msgid="1136599216568805644">"Preostala količina podataka"</string>
- <string name="quick_settings_cellular_detail_over_limit" msgid="4561921367680636235">"Preko ograničenja"</string>
- <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"Iskoristili ste <xliff:g id="DATA_USED">%s</xliff:g>"</string>
- <string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Ograničenje od <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Upozorenje za <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Poslovne aplikacije"</string>
- <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Noćno svetlo"</string>
- <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Uključuje se po zalasku sunca"</string>
- <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Do izlaska sunca"</string>
- <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
- <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
- <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tamna tema"</string>
- <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Ušteda baterije"</string>
- <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Uključuje se po zalasku sunca"</string>
- <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do izlaska sunca"</string>
- <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
- <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
- <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Uključuje se u vreme za spavanje"</string>
- <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"Dok se vreme za spavanje ne završi"</string>
+ <string name="quick_settings_internet_label" msgid="6603068555872455463">"Интернет"</string>
+ <string name="quick_settings_networks_available" msgid="1875138606855420438">"Мреже су доступне"</string>
+ <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Мреже нису доступне"</string>
+ <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Није доступна ниједна WiFi мрежа"</string>
+ <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Укључује се..."</string>
+ <string name="quick_settings_cast_title" msgid="2279220930629235211">"Пребацивање екрана"</string>
+ <string name="quick_settings_casting" msgid="1435880708719268055">"Пребацивање"</string>
+ <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Неименовани уређај"</string>
+ <string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Није доступан ниједан уређај"</string>
+ <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"WiFi није повезан"</string>
+ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Осветљеност"</string>
+ <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Инверзија боја"</string>
+ <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекција боја"</string>
+ <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управљаjте корисницима"</string>
+ <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string>
+ <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Затвори"</string>
+ <string name="quick_settings_connected" msgid="3873605509184830379">"Повезан"</string>
+ <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Повезано, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="quick_settings_connecting" msgid="2381969772953268809">"Повезује се..."</string>
+ <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Хотспот"</string>
+ <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Укључује се..."</string>
+ <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Уштеда података је укључена"</string>
+ <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# уређај}one{# уређај}few{# уређаја}other{# уређаја}}"</string>
+ <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Лампа"</string>
+ <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Користи се камера"</string>
+ <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобилни подаци"</string>
+ <string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Потрошња података"</string>
+ <string name="quick_settings_cellular_detail_remaining_data" msgid="1136599216568805644">"Преостала количина података"</string>
+ <string name="quick_settings_cellular_detail_over_limit" msgid="4561921367680636235">"Преко ограничења"</string>
+ <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"Искористили сте <xliff:g id="DATA_USED">%s</xliff:g>"</string>
+ <string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Ограничење од <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+ <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Упозорење за <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+ <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Пословне апликације"</string>
+ <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Ноћно светло"</string>
+ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Укључује се по заласку сунца"</string>
+ <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"До изласка сунца"</string>
+ <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Укључује се у <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"До <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Тамна тема"</string>
+ <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Уштеда батерије"</string>
+ <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Укључује се по заласку сунца"</string>
+ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изласка сунца"</string>
+ <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Укључује се у <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Укључује се у време за спавање"</string>
+ <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"Док се време за спавање не заврши"</string>
<string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
- <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string>
- <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string>
- <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Snimanje ekrana"</string>
- <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Počnite"</string>
- <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavite"</string>
- <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Režim jednom rukom"</string>
- <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite da odblokirate mikrofon uređaja?"</string>
- <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite da odblokirate kameru uređaja?"</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite da odblokirate kameru i mikrofon uređaja?"</string>
- <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ovim će se odblokirati pristup za sve aplikacije i usluge koje imaju dozvolu za korišćenje mikrofona."</string>
- <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ovim će se odblokirati pristup za sve aplikacije i usluge koje imaju dozvolu za korišćenje kamere."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Ovim će se odblokirati pristup za sve aplikacije i usluge koje imaju dozvolu za korišćenje kamere ili mikrofona."</string>
- <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Mikrofon je blokiran"</string>
- <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Kamera je blokirana"</string>
- <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Mikrofon i kamera su blokirani"</string>
- <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"Da biste odblokirali, pomerite prekidač za privatnost na uređaju na poziciju uključeno za mikrofon kako biste omogućili pristup mikrofonu. Pogledajte priručnik za uređaj da biste pronašli prekidač za privatnost na uređaju."</string>
- <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"Da biste odblokirali, pomerite prekidač za privatnost na uređaju na poziciju uključeno za kameru kako biste omogućili pristup kameri. Pogledajte priručnik za uređaj da biste pronašli prekidač za privatnost na uređaju."</string>
- <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"Da biste ih odblokirali, pomerite prekidač za privatnost na uređaju na poziciju odblokirano kako biste omogućili pristup. Pogledajte priručnik za uređaj da biste pronašli prekidač za privatnost na uređaju."</string>
- <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Mikrofon je dostupan"</string>
- <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Kamera je dostupna"</string>
- <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Mikrofon i kamera su dostupni"</string>
- <string name="media_seamless_other_device" msgid="4654849800789196737">"Drugi uređaj"</string>
- <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Uključi/isključi pregled"</string>
- <string name="zen_priority_introduction" msgid="3159291973383796646">"Neće vas uznemiravati zvukovi i vibracije osim za alarme, podsetnike, događaje i pozivaoce koje navedete. I dalje ćete čuti sve što odaberete da pustite, uključujući muziku, video snimke i igre."</string>
- <string name="zen_alarms_introduction" msgid="3987266042682300470">"Neće vas uznemiravati zvukovi i vibracije osim za alarme. I dalje ćete čuti sve što odaberete da pustite, uključujući muziku, video snimke i igre."</string>
- <string name="zen_priority_customize_button" msgid="4119213187257195047">"Prilagodi"</string>
- <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Ovo blokira SVE zvukove i vibracije uključujući alarme, muziku, video snimke i igre. I dalje ćete moći da upućujete pozive."</string>
- <string name="zen_silence_introduction" msgid="6117517737057344014">"Ovo blokira SVE zvukove i vibracije uključujući alarme, muziku, video snimke i igre."</string>
- <string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite ponovo da biste otvorili"</string>
- <string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
- <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string>
- <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili."</string>
- <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Otključano je licem. Prevucite nagore da biste otvorili."</string>
- <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano je licem. Pritisnite ikonu otključavanja da biste otvorili."</string>
- <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano je licem. Pritisnite da biste otvorili."</string>
- <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
- <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Lice prepoznato. Pritisnite ikonu otključavanja da biste otvorili."</string>
- <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Otključano je licem"</string>
- <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Lice je prepoznato"</string>
+ <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC је онемогућен"</string>
+ <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC је омогућен"</string>
+ <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Снимање екрана"</string>
+ <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Почните"</string>
+ <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Зауставите"</string>
+ <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Режим једном руком"</string>
+ <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Желите да одблокирате микрофон уређаја?"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Желите да одблокирате камеру уређаја?"</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Желите да одблокирате камеру и микрофон уређаја?"</string>
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Овим ће се одблокирати приступ за све апликације и услуге које имају дозволу за коришћење микрофона."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Овим ће се одблокирати приступ за све апликације и услуге које имају дозволу за коришћење камере."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Овим ће се одблокирати приступ за све апликације и услуге које имају дозволу за коришћење камере или микрофона."</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Микрофон је блокиран"</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Камера је блокирана"</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Микрофон и камера су блокирани"</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"Да бисте одблокирали, померите прекидач за приватност на уређају на позицију укључено за микрофон како бисте омогућили приступ микрофону. Погледајте приручник за уређај да бисте пронашли прекидач за приватност на уређају."</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"Да бисте одблокирали, померите прекидач за приватност на уређају на позицију укључено за камеру како бисте омогућили приступ камери. Погледајте приручник за уређај да бисте пронашли прекидач за приватност на уређају."</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"Да бисте их одблокирали, померите прекидач за приватност на уређају на позицију одблокирано како бисте омогућили приступ. Погледајте приручник за уређај да бисте пронашли прекидач за приватност на уређају."</string>
+ <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Микрофон је доступан"</string>
+ <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Камера је доступна"</string>
+ <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Микрофон и камера су доступни"</string>
+ <string name="media_seamless_other_device" msgid="4654849800789196737">"Други уређај"</string>
+ <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Укључи/искључи преглед"</string>
+ <string name="zen_priority_introduction" msgid="3159291973383796646">"Неће вас узнемиравати звукови и вибрације осим за аларме, подсетнике, догађаје и позиваоце које наведете. И даље ћете чути све што одаберете да пустите, укључујући музику, видео снимке и игре."</string>
+ <string name="zen_alarms_introduction" msgid="3987266042682300470">"Неће вас узнемиравати звукови и вибрације осим за аларме. И даље ћете чути све што одаберете да пустите, укључујући музику, видео снимке и игре."</string>
+ <string name="zen_priority_customize_button" msgid="4119213187257195047">"Прилагоди"</string>
+ <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре. И даље ћете моћи да упућујете позиве."</string>
+ <string name="zen_silence_introduction" msgid="6117517737057344014">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре."</string>
+ <string name="notification_tap_again" msgid="4477318164947497249">"Додирните поново да бисте отворили"</string>
+ <string name="tap_again" msgid="1315420114387908655">"Додирните поново"</string>
+ <string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
+ <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притисните икону откључавања да бисте отворили."</string>
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Откључано је лицем. Превуците нагоре да бисте отворили."</string>
+ <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Откључано је лицем. Притисните икону откључавања да бисте отворили."</string>
+ <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Откључано је лицем. Притисните да бисте отворили."</string>
+ <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лице је препознато. Притисните да бисте отворили."</string>
+ <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Лице препознато. Притисните икону откључавања да бисте отворили."</string>
+ <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Откључано је лицем"</string>
+ <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Лице је препознато"</string>
<string-array name="udfps_accessibility_touch_hints">
- <item msgid="1901953991150295169">"Pomerite nalevo"</item>
- <item msgid="5558598599408514296">"Pomerite nadole"</item>
- <item msgid="4844142668312841831">"Pomerite nadesno"</item>
- <item msgid="5640521437931460125">"Pomerite nagore"</item>
+ <item msgid="1901953991150295169">"Померите налево"</item>
+ <item msgid="5558598599408514296">"Померите надоле"</item>
+ <item msgid="4844142668312841831">"Померите надесно"</item>
+ <item msgid="5640521437931460125">"Померите нагоре"</item>
</string-array>
- <string name="keyguard_retry" msgid="886802522584053523">"Prevucite nagore da biste probali ponovo"</string>
- <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste koristili NFC"</string>
- <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada organizaciji"</string>
- <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <string name="phone_hint" msgid="6682125338461375925">"Prevucite od ikone za telefon"</string>
- <string name="voice_hint" msgid="7476017460191291417">"Prevucite od ikone za glasovnu pomoć"</string>
- <string name="camera_hint" msgid="4519495795000658637">"Prevucite od ikone za kameru"</string>
- <string name="interruption_level_none_with_warning" msgid="8394434073508145437">"Potpuna tišina. I čitači ekrana će biti isključeni."</string>
- <string name="interruption_level_none" msgid="219484038314193379">"Potpuna tišina"</string>
- <string name="interruption_level_priority" msgid="661294280016622209">"Samo prioritetni prekidi"</string>
- <string name="interruption_level_alarms" msgid="2457850481335846959">"Samo alarmi"</string>
- <string name="interruption_level_none_twoline" msgid="8579382742855486372">"Potpuna\ntišina"</string>
- <string name="interruption_level_priority_twoline" msgid="8523482736582498083">"Samo\npriorit. prekidi"</string>
- <string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"Samo\nalarmi"</string>
- <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Bežično se puni • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
- <string name="keyguard_indication_charging_time" msgid="6492711711891071502">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Puni se • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
- <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Brzo se puni • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
- <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sporo se puni • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
- <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Puni se • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
- <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
- <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
- <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
- <string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli nazad, goste!"</string>
- <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string>
- <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string>
- <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
- <string name="guest_notification_app_name" msgid="2110425506754205509">"Režim gosta"</string>
- <string name="guest_notification_session_active" msgid="5567273684713471450">"Koristite režim gosta"</string>
- <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dodavanjem novog korisnika izaći ćete iz režima gosta i izbrisaćete sve aplikacije i podatke iz aktuelne sesije gosta."</string>
- <string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut maksimalni broj korisnika"</string>
- <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Možete da napravite samo jednog korisnika.}one{Možete da dodate najviše # korisnika.}few{Možete da dodate najviše # korisnika.}other{Možete da dodate najviše # korisnika.}}"</string>
- <string name="user_remove_user_title" msgid="9124124694835811874">"Želite li da uklonite korisnika?"</string>
- <string name="user_remove_user_message" msgid="6702834122128031833">"Sve aplikacije i podaci ovog korisnika će biti izbrisani."</string>
- <string name="user_remove_user_remove" msgid="8387386066949061256">"Ukloni"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> će imati pristup svim informacijama koje se prikazuju na ekranu ili reprodukuju sa uređaja tokom snimanja ili prebacivanja. To obuhvata informacije poput lozinki, informacija o plaćanju, slika, poruka i zvuka koji puštate."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Usluga koja pruža ovu funkciju će imati pristup svim informacijama koje se prikazuju na ekranu ili reprodukuju sa uređaja tokom snimanja ili prebacivanja. To obuhvata informacije poput lozinki, informacija o plaćanju, slika, poruka i zvuka koji puštate."</string>
- <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Želite da počnete snimanje ili prebacivanje?"</string>
- <string name="media_projection_dialog_title" msgid="3316063622495360646">"Želite da počnete snimanje ili prebacivanje pomoću aplikacije <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
- <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Želite da dozvolite deljenje i snimanje za <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
- <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Ceo ekran"</string>
- <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Jedna aplikacija"</string>
- <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Kada delite, snimate ili prebacujete, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
- <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kada delite, snimate ili prebacujete aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
- <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Nastavi"</string>
- <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Delite ili snimite aplikaciju"</string>
- <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Želite da dozvolite ovoj aplikaciji da deli ili snima?"</string>
- <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kada delite, snimate ili prebacujete, ova aplikacija ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
- <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kada delite, snimate ili prebacujete aplikaciju, ova aplikacija ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
- <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokira IT administrator"</string>
- <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Snimanje ekrana je onemogućeno smernicama za uređaj"</string>
- <string name="clear_all_notifications_text" msgid="348312370303046130">"Obriši sve"</string>
- <string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
- <string name="manage_notifications_history_text" msgid="57055985396576230">"Istorija"</string>
- <string name="notification_section_header_incoming" msgid="850925217908095197">"Novo"</string>
- <string name="notification_section_header_gentle" msgid="6804099527336337197">"Nečujno"</string>
- <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obaveštenja"</string>
- <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzacije"</string>
- <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obrišite sva nečujna obaveštenja"</string>
- <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obaveštenja su pauzirana režimom Ne uznemiravaj"</string>
- <string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
- <string name="empty_shade_text" msgid="8935967157319717412">"Nema obaveštenja"</string>
- <string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obaveštenja"</string>
- <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte da vidite starija obaveštenja"</string>
- <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja roditelj"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizacija je vlasnik uređaja i može da nadgleda mrežni saobraćaj"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je vlasnik ovog uređaja i može da nadgleda mrežni saobraćaj"</string>
- <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Vlasnik ovog uređaja je <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, a povezan je na internet preko: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada organizaciji"</string>
- <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet preko VPN-ova"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Vlasnik ovog uređaja je <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, a povezan je na internet preko VPN-ova"</string>
- <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizacija može da prati mrežni saobraćaj na poslovnom profilu"</string>
- <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može da nadgleda mrežni saobraćaj na poslovnom profilu"</string>
- <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Aktivnost na mreži poslovnog profila je vidljiva IT administratoru"</string>
- <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mreža se možda nadgleda"</string>
- <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Ovaj uređaj je povezan na internet preko VPN-ova"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vaše poslovne aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vaše lične aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Ovaj uređaj je povezan na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajima"</string>
+ <string name="keyguard_retry" msgid="886802522584053523">"Превуците нагоре да бисте пробали поново"</string>
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Откључајте да бисте користили NFC"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Овај уређај припада организацији"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="phone_hint" msgid="6682125338461375925">"Превуците од иконе за телефон"</string>
+ <string name="voice_hint" msgid="7476017460191291417">"Превуците од иконе за гласовну помоћ"</string>
+ <string name="camera_hint" msgid="4519495795000658637">"Превуците од иконе за камеру"</string>
+ <string name="interruption_level_none_with_warning" msgid="8394434073508145437">"Потпуна тишина. И читачи екрана ће бити искључени."</string>
+ <string name="interruption_level_none" msgid="219484038314193379">"Потпуна тишина"</string>
+ <string name="interruption_level_priority" msgid="661294280016622209">"Само приоритетни прекиди"</string>
+ <string name="interruption_level_alarms" msgid="2457850481335846959">"Само аларми"</string>
+ <string name="interruption_level_none_twoline" msgid="8579382742855486372">"Потпуна\nтишина"</string>
+ <string name="interruption_level_priority_twoline" msgid="8523482736582498083">"Само\nприорит. прекиди"</string>
+ <string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"Само\nаларми"</string>
+ <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Бежично се пуни • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
+ <string name="keyguard_indication_charging_time" msgid="6492711711891071502">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Пуни се • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Брзо се пуни • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Споро се пуни • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
+ <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Пуни се • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
+ <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string>
+ <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падајући мени"</string>
+ <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
+ <string name="guest_wipe_session_title" msgid="7147965814683990944">"Добро дошли назад, госте!"</string>
+ <string name="guest_wipe_session_message" msgid="3393823610257065457">"Желите ли да наставите сесију?"</string>
+ <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни из почетка"</string>
+ <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, настави"</string>
+ <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим госта"</string>
+ <string name="guest_notification_session_active" msgid="5567273684713471450">"Користите режим госта"</string>
+ <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Додавањем новог корисника изаћи ћете из режима госта и избрисаћете све апликације и податке из актуелне сесије госта."</string>
+ <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут максимални број корисника"</string>
+ <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Можете да направите само једног корисника.}one{Можете да додате највише # корисника.}few{Можете да додате највише # корисника.}other{Можете да додате највише # корисника.}}"</string>
+ <string name="user_remove_user_title" msgid="9124124694835811874">"Желите ли да уклоните корисника?"</string>
+ <string name="user_remove_user_message" msgid="6702834122128031833">"Све апликације и подаци овог корисника ће бити избрисани."</string>
+ <string name="user_remove_user_remove" msgid="8387386066949061256">"Уклони"</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ће имати приступ свим информацијама које се приказују на екрану или репродукују са уређаја током снимања или пребацивања. То обухвата информације попут лозинки, информација о плаћању, слика, порука и звука који пуштате."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Услуга која пружа ову функцију ће имати приступ свим информацијама које се приказују на екрану или репродукују са уређаја током снимања или пребацивања. То обухвата информације попут лозинки, информација о плаћању, слика, порука и звука који пуштате."</string>
+ <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Желите да почнете снимање или пребацивање?"</string>
+ <string name="media_projection_dialog_title" msgid="3316063622495360646">"Желите да почнете снимање или пребацивање помоћу апликације <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
+ <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Желите да дозволите дељење и снимање за <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
+ <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Цео екран"</string>
+ <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"Једна апликација"</string>
+ <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"Када делите, снимате или пребацујете, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
+ <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Када делите, снимате или пребацујете апликацију, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
+ <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Настави"</string>
+ <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Делите или снимите апликацију"</string>
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Желите да дозволите овој апликацији да дели или снима?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Када делите, снимате или пребацујете, ова апликација има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Када делите, снимате или пребацујете апликацију, ова апликација има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Блокира ИТ администратор"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Снимање екрана је онемогућено смерницама за уређај"</string>
+ <string name="clear_all_notifications_text" msgid="348312370303046130">"Обриши све"</string>
+ <string name="manage_notifications_text" msgid="6885645344647733116">"Управљајте"</string>
+ <string name="manage_notifications_history_text" msgid="57055985396576230">"Историја"</string>
+ <string name="notification_section_header_incoming" msgid="850925217908095197">"Ново"</string>
+ <string name="notification_section_header_gentle" msgid="6804099527336337197">"Нечујно"</string>
+ <string name="notification_section_header_alerting" msgid="5581175033680477651">"Обавештења"</string>
+ <string name="notification_section_header_conversations" msgid="821834744538345661">"Конверзације"</string>
+ <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Обришите сва нечујна обавештења"</string>
+ <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Обавештења су паузирана режимом Не узнемиравај"</string>
+ <string name="media_projection_action_text" msgid="3634906766918186440">"Започни"</string>
+ <string name="empty_shade_text" msgid="8935967157319717412">"Нема обавештења"</string>
+ <string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нових обавештења"</string>
+ <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Откључајте да видите старија обавештења"</string>
+ <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Овим уређајем управља родитељ"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организација је власник уређаја и може да надгледа мрежни саобраћај"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> је власник овог уређаја и може да надгледа мрежни саобраћај"</string>
+ <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Овај уређај припада вашој организацији и повезан је на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Власник овог уређаја је <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, а повезан је на интернет преко: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Овај уређај припада организацији"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Овај уређај припада вашој организацији и повезан је на интернет преко VPN-ова"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Власник овог уређаја је <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, а повезан је на интернет преко VPN-ова"</string>
+ <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Организација може да прати мрежни саобраћај на пословном профилу"</string>
+ <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> може да надгледа мрежни саобраћај на пословном профилу"</string>
+ <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Активност на мрежи пословног профила је видљива ИТ администратору"</string>
+ <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Мрежа се можда надгледа"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Овај уређај је повезан на интернет преко VPN-ова"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Ваше пословне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Ваше личне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Овај уређај је повезан на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управљање уређајима"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
- <string name="monitoring_subtitle_network_logging" msgid="2444199331891219596">"Evidentiranje mreže"</string>
- <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"CA sertifikati"</string>
- <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži smernice"</string>
- <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Prikaži kontrole"</string>
- <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
- <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> možda može da pristupa podacima povezanim sa ovim uređajem, da upravlja aplikacijama i da menja podešavanja ovog uređaja.\n\nAko imate pitanja, obratite se organizaciji <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
- <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada organizaciji.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
- <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizacija je na ovom uređaju instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
- <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizacija je na poslovnom profilu instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
- <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Na ovom uređaju je instaliran autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
- <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na uređaju."</string>
- <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na poslovnom profilu, ali ne i na ličnom profilu."</string>
- <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Ovaj uređaj je povezan na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži, uključujući imejlove i podatke pregledanja, vidljiva je IT administratoru."</string>
- <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Ovaj uređaj je povezan na internet preko: <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vaša aktivnost na mreži, uključujući imejlove i podatke pregledanja, vidljiva je IT administratoru."</string>
- <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vaše poslovne aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži u poslovnim aplikacijama, uključujući imejlove i podatke pregledanja, vidljiva je IT administratoru i dobavljaču VPN-a."</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vaše lične aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži, uključujući imejlove i podatke pregledanja, vidljiva je dobavljaču VPN-a."</string>
+ <string name="monitoring_subtitle_network_logging" msgid="2444199331891219596">"Евидентирање мреже"</string>
+ <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"CA сертификати"</string>
+ <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Прикажи смернице"</string>
+ <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Прикажи контроле"</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
+ <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> можда може да приступа подацима повезаним са овим уређајем, да управља апликацијама и да мења подешавања овог уређаја.\n\nАко имате питања, обратите се организацији <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Овај уређај припада организацији.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
+ <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Организација је на овом уређају инсталирала ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
+ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Организација је на пословном профилу инсталирала ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
+ <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На овом уређају је инсталиран ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
+ <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Администратор је укључио евидентирање мреже, које прати саобраћај на уређају."</string>
+ <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Администратор је укључио евидентирање мреже, које прати саобраћај на пословном профилу, али не и на личном профилу."</string>
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Овај уређај је повезан на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>. Ваша активност на мрежи, укључујући имејлове и податке прегледања, видљива је ИТ администратору."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Овај уређај је повезан на интернет преко: <xliff:g id="VPN_APP_0">%1$s</xliff:g> и <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Ваша активност на мрежи, укључујући имејлове и податке прегледања, видљива је ИТ администратору."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Ваше пословне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>. Ваша активност на мрежи у пословним апликацијама, укључујући имејлове и податке прегледања, видљива је ИТ администратору и добављачу VPN-а."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Ваше личне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>. Ваша активност на мрежи, укључујући имејлове и податке прегледања, видљива је добављачу VPN-а."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
- <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Otvori podešavanja VPN-a"</string>
- <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Ovim uređajem upravlja roditelj. Roditelj može da vidi informacije, kao što su aplikacije koje koristiš, tvoju lokaciju i vreme ispred ekrana, i da upravlja njima."</string>
+ <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Отвори подешавања VPN-а"</string>
+ <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Овим уређајем управља родитељ. Родитељ може да види информације, као што су апликације које користиш, твоју локацију и време испред екрана, и да управља њима."</string>
<string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
- <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Pouzdani agent sprečava zaključavanje"</string>
+ <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Поуздани агент спречава закључавање"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <string name="accessibility_volume_settings" msgid="1458961116951564784">"Podešavanja zvuka"</string>
- <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatski titl za medije"</string>
- <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Opis titla"</string>
- <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Preklapanje titlova"</string>
- <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"omogućite"</string>
- <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogućite"</string>
- <string name="sound_settings" msgid="8874581353127418308">"Zvuk i vibriranje"</string>
- <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Podešavanja"</string>
- <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikacija je zakačena"</string>
- <string name="screen_pinning_description" msgid="8699395373875667743">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Nazad i Pregled da biste ga otkačili."</string>
- <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Nazad i Početna da biste ga otkačili."</string>
- <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Stalno će se prikazivati dok je ne otkačite. Prevucite nagore i zadržite da biste je otkačili."</string>
- <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Pregled da biste ga otkačili."</string>
- <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Početna da biste ga otkačili."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Mogu da budu dostupni lični podaci (kao što su kontakti i sadržaj imejlova)."</string>
- <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Zakačena aplikacija može da otvara druge aplikacije."</string>
- <string name="screen_pinning_toast" msgid="8177286912533744328">"Da biste otkačili ovu aplikaciju, dodirnite i zadržite dugmad Nazad i Pregled"</string>
- <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Da biste otkačili ovu aplikaciju, dodirnite i zadržite dugmad Nazad i Početna"</string>
- <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Da biste otkačili ovu aplikaciju, prevucite nagore i zadržite"</string>
- <string name="screen_pinning_positive" msgid="3285785989665266984">"Važi"</string>
- <string name="screen_pinning_negative" msgid="6882816864569211666">"Ne, hvala"</string>
- <string name="screen_pinning_start" msgid="7483998671383371313">"Aplikacija je zakačena"</string>
- <string name="screen_pinning_exit" msgid="4553787518387346893">"Aplikacija je otkačena"</string>
- <string name="stream_voice_call" msgid="7468348170702375660">"Poziv"</string>
- <string name="stream_system" msgid="7663148785370565134">"Sistem"</string>
- <string name="stream_ring" msgid="7550670036738697526">"Zvono"</string>
- <string name="stream_music" msgid="2188224742361847580">"Mediji"</string>
- <string name="stream_alarm" msgid="16058075093011694">"Alarm"</string>
- <string name="stream_notification" msgid="7930294049046243939">"Obaveštenje"</string>
+ <string name="accessibility_volume_settings" msgid="1458961116951564784">"Подешавања звука"</string>
+ <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Аутоматски титл за медије"</string>
+ <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Опис титла"</string>
+ <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Преклапање титлова"</string>
+ <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"омогућите"</string>
+ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"онемогућите"</string>
+ <string name="sound_settings" msgid="8874581353127418308">"Звук и вибрирање"</string>
+ <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Подешавања"</string>
+ <string name="screen_pinning_title" msgid="9058007390337841305">"Апликација је закачена"</string>
+ <string name="screen_pinning_description" msgid="8699395373875667743">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Назад и Преглед да бисте га откачили."</string>
+ <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Назад и Почетна да бисте га откачили."</string>
+ <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Стално ће се приказивати док је не откачите. Превуците нагоре и задржите да бисте је откачили."</string>
+ <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Преглед да бисте га откачили."</string>
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Почетна да бисте га откачили."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Могу да буду доступни лични подаци (као што су контакти и садржај имејлова)."</string>
+ <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Закачена апликација може да отвара друге апликације."</string>
+ <string name="screen_pinning_toast" msgid="8177286912533744328">"Да бисте откачили ову апликацију, додирните и задржите дугмад Назад и Преглед"</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Да бисте откачили ову апликацију, додирните и задржите дугмад Назад и Почетна"</string>
+ <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Да бисте откачили ову апликацију, превуците нагоре и задржите"</string>
+ <string name="screen_pinning_positive" msgid="3285785989665266984">"Важи"</string>
+ <string name="screen_pinning_negative" msgid="6882816864569211666">"Не, хвала"</string>
+ <string name="screen_pinning_start" msgid="7483998671383371313">"Апликација је закачена"</string>
+ <string name="screen_pinning_exit" msgid="4553787518387346893">"Апликација је откачена"</string>
+ <string name="stream_voice_call" msgid="7468348170702375660">"Позив"</string>
+ <string name="stream_system" msgid="7663148785370565134">"Систем"</string>
+ <string name="stream_ring" msgid="7550670036738697526">"Звоно"</string>
+ <string name="stream_music" msgid="2188224742361847580">"Медији"</string>
+ <string name="stream_alarm" msgid="16058075093011694">"Аларм"</string>
+ <string name="stream_notification" msgid="7930294049046243939">"Обавештење"</string>
<string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
- <string name="stream_dtmf" msgid="7322536356554673067">"Višestruka frekvencija dualnog tona"</string>
- <string name="stream_accessibility" msgid="3873610336741987152">"Pristupačnost"</string>
- <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Aktiviraj zvono"</string>
- <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriraj"</string>
- <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Isključi zvuk"</string>
- <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dodirnite da biste uključili zvuk."</string>
- <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dodirnite da biste podesili na vibraciju. Zvuk usluga pristupačnosti će možda biti isključen."</string>
- <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da biste isključili zvuk. Zvuk usluga pristupačnosti će možda biti isključen."</string>
- <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da biste podesili na vibraciju."</string>
- <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da biste isključili zvuk."</string>
- <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promenili režim zvona"</string>
- <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string>
- <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string>
- <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibracija"</string>
- <string name="volume_dialog_title" msgid="6502703403483577940">"Kontrole za jačinu zvuka za %s"</string>
- <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Melodija zvona za pozive i obaveštenja je uključena (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
- <string name="system_ui_tuner" msgid="1471348823289954729">"Tjuner za korisnički interfejs sistema"</string>
- <string name="status_bar" msgid="4357390266055077437">"Statusna traka"</string>
- <string name="demo_mode" msgid="263484519766901593">"Režim demonstracije za korisnički interfejs sistema"</string>
- <string name="enable_demo_mode" msgid="3180345364745966431">"Omogući režim demonstracije"</string>
- <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži režim demonstracije"</string>
- <string name="status_bar_ethernet" msgid="5690979758988647484">"Eternet"</string>
- <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
- <string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string>
- <string name="wallet_empty_state_label" msgid="7776761245237530394">"Obavite konfigurisanje da biste mogli brže i sigurnije da kupujete pomoću telefona"</string>
- <string name="wallet_app_button_label" msgid="7123784239111190992">"Prikaži sve"</string>
- <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Dodirnite i otvorite"</string>
- <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ažurira se"</string>
- <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključaj radi korišćenja"</string>
- <string name="wallet_error_generic" msgid="257704570182963611">"Došlo je do problema pri preuzimanju kartica. Probajte ponovo kasnije"</string>
- <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Podešavanja zaključanog ekrana"</string>
- <string name="qr_code_scanner_title" msgid="1938155688725760702">"Skener QR koda"</string>
- <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Ažurira se"</string>
- <string name="status_bar_work" msgid="5238641949837091056">"Poslovni profil"</string>
- <string name="status_bar_airplane" msgid="4848702508684541009">"Režim rada u avionu"</string>
- <string name="zen_alarm_warning" msgid="7844303238486849503">"Nećete čuti sledeći alarm u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="alarm_template" msgid="2234991538018805736">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="alarm_template_far" msgid="3561752195856839456">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string>
- <string name="accessibility_managed_profile" msgid="4703836746209377356">"Poslovni profil"</string>
- <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
- <string name="tuner_warning" msgid="1861736288458481650">"Tjuner za korisnički interfejs sistema vam pruža dodatne načine za podešavanje i prilagođavanje Android korisničkog interfejsa. Ove eksperimentalne funkcije mogu da se promene, otkažu ili nestanu u budućim izdanjima. Budite oprezni."</string>
- <string name="tuner_persistent_warning" msgid="230466285569307806">"Ove eksperimentalne funkcije mogu da se promene, otkažu ili nestanu u budućim izdanjima. Budite oprezni."</string>
- <string name="got_it" msgid="477119182261892069">"Važi"</string>
- <string name="tuner_toast" msgid="3812684836514766951">"Čestitamo! Tjuner za korisnički interfejs sistema je dodat u Podešavanja"</string>
- <string name="remove_from_settings" msgid="633775561782209994">"Ukloni iz Podešavanja"</string>
- <string name="remove_from_settings_prompt" msgid="551565437265615426">"Želite li da uklonite Tjuner za korisnički interfejs sistema iz Podešavanja i da prestanete da koristite sve njegove funkcije?"</string>
- <string name="enable_bluetooth_title" msgid="866883307336662596">"Želite li da uključite Bluetooth?"</string>
- <string name="enable_bluetooth_message" msgid="6740938333772779717">"Da biste povezali tastaturu sa tabletom, prvo morate da uključite Bluetooth."</string>
- <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"Uključi"</string>
- <string name="tuner_full_importance_settings" msgid="1388025816553459059">"Napredne kontrole za obaveštenja"</string>
- <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Uključeno – na osnovu lica"</string>
- <string name="power_notification_controls_description" msgid="1334963837572708952">"Pomoću naprednih kontrola za obaveštenja možete da podesite nivo važnosti od 0. do 5. za obaveštenja aplikacije. \n\n"<b>"5. nivo"</b>" \n– Prikazuju se u vrhu liste obaveštenja \n- Dozvoli prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"4. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"3. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n\n"<b>"2. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n\n"<b>"1. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n– Sakrij na zaključanom ekranu i statusnoj traci \n– Prikazuju se u dnu liste obaveštenja \n\n"<b>"0. nivo"</b>" \n– Blokiraj sva obaveštenja iz aplikacije"</string>
- <string name="inline_done_button" msgid="6043094985588909584">"Gotovo"</string>
- <string name="inline_ok_button" msgid="603075490581280343">"Primeni"</string>
- <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Isključi obaveštenja"</string>
- <string name="notification_silence_title" msgid="8608090968400832335">"Nečujno"</string>
- <string name="notification_alert_title" msgid="3656229781017543655">"Podrazumevano"</string>
- <string name="notification_automatic_title" msgid="3745465364578762652">"Automatska"</string>
- <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka i vibriranja"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka i vibriranja i prikazuje se u nastavku odeljka za konverzacije"</string>
- <string name="notification_channel_summary_default" msgid="3282930979307248890">"Može da zvoni ili vibrira u zavisnosti od podešavanja telefona"</string>
- <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Može da zvoni ili vibrira u zavisnosti od podešavanja telefona. Konverzacije iz aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> se podrazumevano prikazuju u oblačićima."</string>
- <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Neka sistem utvrdi da li ovo obaveštenje treba da emituje zvuk ili da vibrira"</string>
- <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> Unapređeno u Podrazumevano"</string>
- <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Degradirano u Nečujno"</string>
- <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"<b>Status:</b> Rangirano više"</string>
- <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"<b>Status:</b> Rangirano niže"</string>
- <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu"</string>
- <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić"</string>
- <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, prekida režim Ne uznemiravaj"</string>
- <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić, prekida režim Ne uznemiravaj"</string>
- <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
- <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije konverzacije"</string>
- <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ova obaveštenja ne mogu da se menjaju."</string>
- <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obaveštenja o pozivima ne mogu da se menjaju."</string>
- <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ova grupa obaveštenja ne može da se konfiguriše ovde"</string>
- <string name="notification_delegate_header" msgid="1264510071031479920">"Obaveštenje preko proksija"</string>
- <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Sva obaveštenja aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="see_more_title" msgid="7409317011708185729">"Prikaži još"</string>
- <string name="feedback_alerted" msgid="5192459808484271208">"Sistem je ovo obaveštenje automatski <b>unapredio u podrazumevano</b>."</string>
- <string name="feedback_silenced" msgid="9116540317466126457">"Sistem je ovo obaveštenje automatski <b>degradirao u Nečujno</b>."</string>
- <string name="feedback_promoted" msgid="2125562787759780807">"Ovo obaveštenje je automatski <b>rangirano više</b> na traci sa obaveštenjima."</string>
- <string name="feedback_demoted" msgid="951884763467110604">"Ovo obaveštenje je automatski <b>rangirano niže</b> na traci sa obaveštenjima."</string>
- <string name="feedback_prompt" msgid="3656728972307896379">"Pošaljite programeru povratne informacije. Da li je to tačno?"</string>
- <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Kontrole obaveštenja za otvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"Kontrole obaveštenja za zatvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="notification_more_settings" msgid="4936228656989201793">"Još podešavanja"</string>
- <string name="notification_app_settings" msgid="8963648463858039377">"Prilagodi"</string>
- <string name="notification_conversation_bubble" msgid="2242180995373949022">"Prikaži oblačić"</string>
- <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Ukloni oblačiće"</string>
+ <string name="stream_dtmf" msgid="7322536356554673067">"Вишеструка фреквенција дуалног тона"</string>
+ <string name="stream_accessibility" msgid="3873610336741987152">"Приступачност"</string>
+ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Активирај звоно"</string>
+ <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрирај"</string>
+ <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Искључи звук"</string>
+ <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Додирните да бисте укључили звук."</string>
+ <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Додирните да бисте подесили на вибрацију. Звук услуга приступачности ће можда бити искључен."</string>
+ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Додирните да бисте искључили звук. Звук услуга приступачности ће можда бити искључен."</string>
+ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Додирните да бисте подесили на вибрацију."</string>
+ <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Додирните да бисте искључили звук."</string>
+ <string name="volume_ringer_change" msgid="3574969197796055532">"Додирните да бисте променили режим звона"</string>
+ <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"искључите звук"</string>
+ <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"укључите звук"</string>
+ <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрација"</string>
+ <string name="volume_dialog_title" msgid="6502703403483577940">"Контроле за јачину звука за %s"</string>
+ <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Мелодија звона за позиве и обавештења је укључена (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
+ <string name="system_ui_tuner" msgid="1471348823289954729">"Тјунер за кориснички интерфејс система"</string>
+ <string name="status_bar" msgid="4357390266055077437">"Статусна трака"</string>
+ <string name="demo_mode" msgid="263484519766901593">"Режим демонстрације за кориснички интерфејс система"</string>
+ <string name="enable_demo_mode" msgid="3180345364745966431">"Омогући режим демонстрације"</string>
+ <string name="show_demo_mode" msgid="3677956462273059726">"Прикажи режим демонстрације"</string>
+ <string name="status_bar_ethernet" msgid="5690979758988647484">"Етернет"</string>
+ <string name="status_bar_alarm" msgid="87160847643623352">"Аларм"</string>
+ <string name="wallet_title" msgid="5369767670735827105">"Новчаник"</string>
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"Обавите конфигурисање да бисте могли брже и сигурније да купујете помоћу телефона"</string>
+ <string name="wallet_app_button_label" msgid="7123784239111190992">"Прикажи све"</string>
+ <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Додирните и отворите"</string>
+ <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ажурира се"</string>
+ <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Откључај ради коришћења"</string>
+ <string name="wallet_error_generic" msgid="257704570182963611">"Дошло је до проблема при преузимању картица. Пробајте поново касније"</string>
+ <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Подешавања закључаног екрана"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Скенер QR кода"</string>
+ <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Ажурира се"</string>
+ <string name="status_bar_work" msgid="5238641949837091056">"Пословни профил"</string>
+ <string name="status_bar_airplane" msgid="4848702508684541009">"Режим рада у авиону"</string>
+ <string name="zen_alarm_warning" msgid="7844303238486849503">"Нећете чути следећи аларм у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="alarm_template" msgid="2234991538018805736">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="alarm_template_far" msgid="3561752195856839456">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Хотспот"</string>
+ <string name="accessibility_managed_profile" msgid="4703836746209377356">"Пословни профил"</string>
+ <string name="tuner_warning_title" msgid="7721976098452135267">"Забава за неке, али не за све"</string>
+ <string name="tuner_warning" msgid="1861736288458481650">"Тјунер за кориснички интерфејс система вам пружа додатне начине за подешавање и прилагођавање Android корисничког интерфејса. Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string>
+ <string name="tuner_persistent_warning" msgid="230466285569307806">"Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string>
+ <string name="got_it" msgid="477119182261892069">"Важи"</string>
+ <string name="tuner_toast" msgid="3812684836514766951">"Честитамо! Тјунер за кориснички интерфејс система је додат у Подешавања"</string>
+ <string name="remove_from_settings" msgid="633775561782209994">"Уклони из Подешавања"</string>
+ <string name="remove_from_settings_prompt" msgid="551565437265615426">"Желите ли да уклоните Тјунер за кориснички интерфејс система из Подешавања и да престанете да користите све његове функције?"</string>
+ <string name="enable_bluetooth_title" msgid="866883307336662596">"Желите ли да укључите Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="6740938333772779717">"Да бисте повезали тастатуру са таблетом, прво морате да укључите Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"Укључи"</string>
+ <string name="tuner_full_importance_settings" msgid="1388025816553459059">"Напредне контроле за обавештења"</string>
+ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Укључено – на основу лица"</string>
+ <string name="power_notification_controls_description" msgid="1334963837572708952">"Помоћу напредних контрола за обавештења можете да подесите ниво важности од 0. до 5. за обавештења апликације. \n\n"<b>"5. ниво"</b>" \n– Приказују се у врху листе обавештења \n- Дозволи прекид режима целог екрана \n– Увек завируј \n\n"<b>"4. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Увек завируј \n\n"<b>"3. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n\n"<b>"2. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n\n"<b>"1. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n– Сакриј на закључаном екрану и статусној траци \n– Приказују се у дну листе обавештења \n\n"<b>"0. ниво"</b>" \n– Блокирај сва обавештења из апликације"</string>
+ <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string>
+ <string name="inline_ok_button" msgid="603075490581280343">"Примени"</string>
+ <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Искључи обавештења"</string>
+ <string name="notification_silence_title" msgid="8608090968400832335">"Нечујно"</string>
+ <string name="notification_alert_title" msgid="3656229781017543655">"Подразумевано"</string>
+ <string name="notification_automatic_title" msgid="3745465364578762652">"Аутоматска"</string>
+ <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звука и вибрирања"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звука и вибрирања и приказује се у наставку одељка за конверзације"</string>
+ <string name="notification_channel_summary_default" msgid="3282930979307248890">"Може да звони или вибрира у зависности од подешавања телефона"</string>
+ <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Може да звони или вибрира у зависности од подешавања телефона. Конверзације из апликације <xliff:g id="APP_NAME">%1$s</xliff:g> се подразумевано приказују у облачићима."</string>
+ <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Нека систем утврди да ли ово обавештење треба да емитује звук или да вибрира"</string>
+ <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Статус:</b> Унапређено у Подразумевано"</string>
+ <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Статус:</b> Деградирано у Нечујно"</string>
+ <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"<b>Статус:</b> Рангирано више"</string>
+ <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"<b>Статус:</b> Рангирано ниже"</string>
+ <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану"</string>
+ <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, прекида режим Не узнемиравај"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић, прекида режим Не узнемиравај"</string>
+ <string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
+ <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не подржава функције конверзације"</string>
+ <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ова обавештења не могу да се мењају."</string>
+ <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Обавештења о позивима не могу да се мењају."</string>
+ <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ова група обавештења не може да се конфигурише овде"</string>
+ <string name="notification_delegate_header" msgid="1264510071031479920">"Обавештење преко проксија"</string>
+ <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Сва обавештења апликације <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="see_more_title" msgid="7409317011708185729">"Прикажи још"</string>
+ <string name="feedback_alerted" msgid="5192459808484271208">"Систем је ово обавештење аутоматски <b>унапредио у подразумевано</b>."</string>
+ <string name="feedback_silenced" msgid="9116540317466126457">"Систем је ово обавештење аутоматски <b>деградирао у Нечујно</b>."</string>
+ <string name="feedback_promoted" msgid="2125562787759780807">"Ово обавештење је аутоматски <b>рангирано више</b> на траци са обавештењима."</string>
+ <string name="feedback_demoted" msgid="951884763467110604">"Ово обавештење је аутоматски <b>рангирано ниже</b> на траци са обавештењима."</string>
+ <string name="feedback_prompt" msgid="3656728972307896379">"Пошаљите програмеру повратне информације. Да ли је то тачно?"</string>
+ <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Контроле обавештења за отварање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"Контроле обавештења за затварање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="notification_more_settings" msgid="4936228656989201793">"Још подешавања"</string>
+ <string name="notification_app_settings" msgid="8963648463858039377">"Прилагоди"</string>
+ <string name="notification_conversation_bubble" msgid="2242180995373949022">"Прикажи облачић"</string>
+ <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Уклони облачиће"</string>
<string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="notification_menu_gear_description" msgid="6429668976593634862">"kontrole obaveštenja"</string>
- <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opcije za odlaganje obaveštenja"</string>
- <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Podseti me"</string>
- <string name="snooze_undo" msgid="2738844148845992103">"Opozovi"</string>
- <string name="snoozed_for_time" msgid="7586689374860469469">"Odloženo je za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
- <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# sat}=2{# sata}one{# sat}few{# sata}other{# sati}}"</string>
- <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}one{# minut}few{# minuta}other{# minuta}}"</string>
- <string name="battery_detail_switch_title" msgid="6940976502957380405">"Ušteda baterije"</string>
- <string name="keyboard_key_button_template" msgid="8005673627272051429">"Dugme <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="keyboard_key_home" msgid="3734400625170020657">"Taster Početna"</string>
- <string name="keyboard_key_back" msgid="4185420465469481999">"Taster Nazad"</string>
- <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Taster sa strelicom nagore"</string>
- <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Taster sa strelicom nadole"</string>
- <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Taster sa strelicom nalevo"</string>
- <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Taster sa strelicom nadesno"</string>
- <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Taster sa centralnom strelicom"</string>
+ <string name="notification_menu_gear_description" msgid="6429668976593634862">"контроле обавештења"</string>
+ <string name="notification_menu_snooze_description" msgid="4740133348901973244">"опције за одлагање обавештења"</string>
+ <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Подсети ме"</string>
+ <string name="snooze_undo" msgid="2738844148845992103">"Опозови"</string>
+ <string name="snoozed_for_time" msgid="7586689374860469469">"Одложено је за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+ <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# сат}=2{# сата}one{# сат}few{# сата}other{# сати}}"</string>
+ <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# минут}one{# минут}few{# минута}other{# минута}}"</string>
+ <string name="battery_detail_switch_title" msgid="6940976502957380405">"Уштеда батерије"</string>
+ <string name="keyboard_key_button_template" msgid="8005673627272051429">"Дугме <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="3734400625170020657">"Тастер Почетна"</string>
+ <string name="keyboard_key_back" msgid="4185420465469481999">"Тастер Назад"</string>
+ <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Тастер са стрелицом нагоре"</string>
+ <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Тастер са стрелицом надоле"</string>
+ <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Тастер са стрелицом налево"</string>
+ <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Тастер са стрелицом надесно"</string>
+ <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Тастер са централном стрелицом"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
- <string name="keyboard_key_space" msgid="6980847564173394012">"Razmak"</string>
+ <string name="keyboard_key_space" msgid="6980847564173394012">"Размак"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
- <string name="keyboard_key_backspace" msgid="4095278312039628074">"Taster za brisanje unazad"</string>
- <string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Taster za reprodukciju/pauziranje"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Taster za zaustavljanje"</string>
- <string name="keyboard_key_media_next" msgid="8502476691227914952">"Taster Sledeća"</string>
- <string name="keyboard_key_media_previous" msgid="5637875709190955351">"Taster Prethodna"</string>
- <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Taster za premotavanje unazad"</string>
- <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"Taster za premotavanje unapred"</string>
- <string name="keyboard_key_page_up" msgid="173914303254199845">"Taster za stranicu nagore"</string>
- <string name="keyboard_key_page_down" msgid="9035902490071829731">"Taster za stranicu nadole"</string>
- <string name="keyboard_key_forward_del" msgid="5325501825762733459">"Taster za brisanje"</string>
- <string name="keyboard_key_move_home" msgid="3496502501803911971">"Taster Početna"</string>
- <string name="keyboard_key_move_end" msgid="99190401463834854">"Taster za kraj"</string>
- <string name="keyboard_key_insert" msgid="4621692715704410493">"Taster za umetanje"</string>
+ <string name="keyboard_key_backspace" msgid="4095278312039628074">"Тастер за брисање уназад"</string>
+ <string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Тастер за репродукцију/паузирање"</string>
+ <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Тастер за заустављање"</string>
+ <string name="keyboard_key_media_next" msgid="8502476691227914952">"Тастер Следећа"</string>
+ <string name="keyboard_key_media_previous" msgid="5637875709190955351">"Тастер Претходна"</string>
+ <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Тастер за премотавање уназад"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"Тастер за премотавање унапред"</string>
+ <string name="keyboard_key_page_up" msgid="173914303254199845">"Тастер за страницу нагоре"</string>
+ <string name="keyboard_key_page_down" msgid="9035902490071829731">"Тастер за страницу надоле"</string>
+ <string name="keyboard_key_forward_del" msgid="5325501825762733459">"Тастер за брисање"</string>
+ <string name="keyboard_key_move_home" msgid="3496502501803911971">"Тастер Почетна"</string>
+ <string name="keyboard_key_move_end" msgid="99190401463834854">"Тастер за крај"</string>
+ <string name="keyboard_key_insert" msgid="4621692715704410493">"Тастер за уметање"</string>
<string name="keyboard_key_num_lock" msgid="7209960042043090548">"Num Lock"</string>
- <string name="keyboard_key_numpad_template" msgid="7316338238459991821">"Taster <xliff:g id="NAME">%1$s</xliff:g> na numeričkoj tastaturi"</string>
- <string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"Ukloni prilog"</string>
- <string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"Sistem"</string>
- <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"Početni"</string>
- <string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Nedavni sadržaj"</string>
- <string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"Nazad"</string>
- <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Obaveštenja"</string>
- <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Tasterske prečice"</string>
- <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Promeni raspored tastature"</string>
- <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikacije"</string>
- <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Aplikacija za pomoć"</string>
- <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Pregledač"</string>
- <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakti"</string>
- <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Imejl"</string>
+ <string name="keyboard_key_numpad_template" msgid="7316338238459991821">"Тастер <xliff:g id="NAME">%1$s</xliff:g> на нумеричкој тастатури"</string>
+ <string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"Уклони прилог"</string>
+ <string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"Систем"</string>
+ <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"Почетни"</string>
+ <string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Недавни садржај"</string>
+ <string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"Назад"</string>
+ <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Обавештења"</string>
+ <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Тастерске пречице"</string>
+ <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Промени распоред тастатуре"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Апликације"</string>
+ <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Апликација за помоћ"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Прегледач"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Контакти"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Имејл"</string>
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
- <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
- <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
- <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne uznemiravaj"</string>
- <string name="volume_dnd_silent" msgid="4154597281458298093">"Prečica za dugmad za jačinu zvuka"</string>
- <string name="battery" msgid="769686279459897127">"Baterija"</string>
- <string name="headset" msgid="4485892374984466437">"Naglavne slušalice"</string>
- <string name="accessibility_long_click_tile" msgid="210472753156768705">"Otvorite podešavanja"</string>
- <string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"Slušalice su povezane"</string>
- <string name="accessibility_status_bar_headset" msgid="2699275863720926104">"Naglavne slušalice su povezane"</string>
- <string name="data_saver" msgid="3484013368530820763">"Ušteda podataka"</string>
- <string name="accessibility_data_saver_on" msgid="5394743820189757731">"Ušteda podataka je uključena"</string>
- <string name="switch_bar_on" msgid="1770868129120096114">"Uključeno"</string>
- <string name="switch_bar_off" msgid="5669805115416379556">"Isključeno"</string>
- <string name="tile_unavailable" msgid="3095879009136616920">"Nedostupno"</string>
- <string name="accessibility_tile_disabled_by_policy_action_description" msgid="6958422730461646926">"saznajte više"</string>
- <string name="nav_bar" msgid="4642708685386136807">"Traka za navigaciju"</string>
- <string name="nav_bar_layout" msgid="4716392484772899544">"Raspored"</string>
- <string name="left_nav_bar_button_type" msgid="2634852842345192790">"Dodatni tip levog dugmeta"</string>
- <string name="right_nav_bar_button_type" msgid="4472566498647364715">"Dodatni tip desnog dugmeta"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не узнемиравај"</string>
+ <string name="volume_dnd_silent" msgid="4154597281458298093">"Пречица за дугмад за јачину звука"</string>
+ <string name="battery" msgid="769686279459897127">"Батерија"</string>
+ <string name="headset" msgid="4485892374984466437">"Наглавне слушалице"</string>
+ <string name="accessibility_long_click_tile" msgid="210472753156768705">"Отворите подешавања"</string>
+ <string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"Слушалице су повезане"</string>
+ <string name="accessibility_status_bar_headset" msgid="2699275863720926104">"Наглавне слушалице су повезане"</string>
+ <string name="data_saver" msgid="3484013368530820763">"Уштеда података"</string>
+ <string name="accessibility_data_saver_on" msgid="5394743820189757731">"Уштеда података је укључена"</string>
+ <string name="switch_bar_on" msgid="1770868129120096114">"Укључено"</string>
+ <string name="switch_bar_off" msgid="5669805115416379556">"Искључено"</string>
+ <string name="tile_unavailable" msgid="3095879009136616920">"Недоступно"</string>
+ <string name="accessibility_tile_disabled_by_policy_action_description" msgid="6958422730461646926">"сазнајте више"</string>
+ <string name="nav_bar" msgid="4642708685386136807">"Трака за навигацију"</string>
+ <string name="nav_bar_layout" msgid="4716392484772899544">"Распоред"</string>
+ <string name="left_nav_bar_button_type" msgid="2634852842345192790">"Додатни тип левог дугмета"</string>
+ <string name="right_nav_bar_button_type" msgid="4472566498647364715">"Додатни тип десног дугмета"</string>
<string-array name="nav_bar_buttons">
- <item msgid="2681220472659720036">"Memorija"</item>
- <item msgid="4795049793625565683">"Kôd tastera"</item>
- <item msgid="80697951177515644">"Potvrda rotiranja, prebacivač za tastaturu"</item>
- <item msgid="7626977989589303588">"Ništa"</item>
+ <item msgid="2681220472659720036">"Меморија"</item>
+ <item msgid="4795049793625565683">"Кôд тастера"</item>
+ <item msgid="80697951177515644">"Потврда ротирања, пребацивач за тастатуру"</item>
+ <item msgid="7626977989589303588">"Ништа"</item>
</string-array>
<string-array name="nav_bar_layouts">
- <item msgid="9156773083127904112">"Normalni"</item>
- <item msgid="2019571224156857610">"Kompaktni"</item>
- <item msgid="7453955063378349599">"Uz levu stranu"</item>
- <item msgid="5874146774389433072">"Uz desnu stranu"</item>
+ <item msgid="9156773083127904112">"Нормални"</item>
+ <item msgid="2019571224156857610">"Компактни"</item>
+ <item msgid="7453955063378349599">"Уз леву страну"</item>
+ <item msgid="5874146774389433072">"Уз десну страну"</item>
</string-array>
- <string name="save" msgid="3392754183673848006">"Sačuvaj"</string>
- <string name="reset" msgid="8715144064608810383">"Resetuj"</string>
- <string name="clipboard" msgid="8517342737534284617">"Privremena memorija"</string>
- <string name="accessibility_key" msgid="3471162841552818281">"Prilagođeno dugme za navigaciju"</string>
- <string name="left_keycode" msgid="8211040899126637342">"Levo dugme za kôd tastera"</string>
- <string name="right_keycode" msgid="2480715509844798438">"Desno dugme za kôd tastera"</string>
- <string name="left_icon" msgid="5036278531966897006">"Leva ikona"</string>
- <string name="right_icon" msgid="1103955040645237425">"Desna ikona"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Zadržite i prevucite da biste dodali pločice"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Zadržite i prevucite da biste promenili raspored pločica"</string>
- <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Prevucite ovde da biste uklonili"</string>
- <string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimalan broj pločica je <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
- <string name="qs_edit" msgid="5583565172803472437">"Izmeni"</string>
- <string name="tuner_time" msgid="2450785840990529997">"Vreme"</string>
+ <string name="save" msgid="3392754183673848006">"Сачувај"</string>
+ <string name="reset" msgid="8715144064608810383">"Ресетуј"</string>
+ <string name="clipboard" msgid="8517342737534284617">"Привремена меморија"</string>
+ <string name="accessibility_key" msgid="3471162841552818281">"Прилагођено дугме за навигацију"</string>
+ <string name="left_keycode" msgid="8211040899126637342">"Лево дугме за кôд тастера"</string>
+ <string name="right_keycode" msgid="2480715509844798438">"Десно дугме за кôд тастера"</string>
+ <string name="left_icon" msgid="5036278531966897006">"Лева икона"</string>
+ <string name="right_icon" msgid="1103955040645237425">"Десна икона"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Задржите и превуците да бисте додали плочице"</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Задржите и превуците да бисте променили распоред плочица"</string>
+ <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Превуците овде да бисте уклонили"</string>
+ <string name="drag_to_remove_disabled" msgid="933046987838658850">"Минималан број плочица је <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
+ <string name="qs_edit" msgid="5583565172803472437">"Измени"</string>
+ <string name="tuner_time" msgid="2450785840990529997">"Време"</string>
<string-array name="clock_options">
- <item msgid="3986445361435142273">"Prikaži sate, minute i sekunde"</item>
- <item msgid="1271006222031257266">"Prikaži sate i minute (podrazumevano)"</item>
- <item msgid="6135970080453877218">"Ne prikazuj ovu ikonu"</item>
+ <item msgid="3986445361435142273">"Прикажи сате, минуте и секунде"</item>
+ <item msgid="1271006222031257266">"Прикажи сате и минуте (подразумевано)"</item>
+ <item msgid="6135970080453877218">"Не приказуј ову икону"</item>
</string-array>
<string-array name="battery_options">
- <item msgid="7714004721411852551">"Uvek prikazuj procenat"</item>
- <item msgid="3805744470661798712">"Prikaži procenat tokom punjenja (podrazumevano)"</item>
- <item msgid="8619482474544321778">"Ne prikazuj ovu ikonu"</item>
+ <item msgid="7714004721411852551">"Увек приказуј проценат"</item>
+ <item msgid="3805744470661798712">"Прикажи проценат током пуњења (подразумевано)"</item>
+ <item msgid="8619482474544321778">"Не приказуј ову икону"</item>
</string-array>
- <string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obaveštenja niskog prioriteta"</string>
- <string name="other" msgid="429768510980739978">"Drugo"</string>
- <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"uklonili pločicu"</string>
- <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"dodali pločicu na kraj"</string>
- <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Premestite pločicu"</string>
- <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Dodajte pločicu"</string>
- <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Premestite na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string>
- <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajte na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string>
- <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija"</string>
- <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pločica je dodata"</string>
- <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pločica je uklonjena"</string>
- <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač za Brza podešavanja."</string>
- <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Obaveštenja za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvori Podešavanja."</string>
- <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvori Brza podešavanja."</string>
- <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvori Brza podešavanja."</string>
- <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Prijavljeni ste kao <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"odabrali korisnika"</string>
- <string name="data_connection_no_internet" msgid="691058178914184544">"Nema interneta"</string>
- <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvori podešavanja za <xliff:g id="ID_1">%s</xliff:g>."</string>
- <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Izmeni redosled podešavanja."</string>
- <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni dugmeta za uključivanje"</string>
- <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. strana od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
- <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključan ekran"</string>
- <string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog toplote"</string>
- <string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefon sada normalno radi.\nDodirnite za više informacija"</string>
- <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon je bio prevruć, pa se isključio da se ohladi. Sada radi normalno.\n\nTelefon može previše da se ugreje ako:\n • Koristite aplikacije koje zahtevaju puno resursa (npr. video igre, video ili aplikacije za navigaciju)\n • Preuzimate/otpremate velike datoteke\n • Koristite telefon na visokoj temperaturi"</string>
- <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Pogledajte upozorenja"</string>
- <string name="high_temp_title" msgid="2218333576838496100">"Telefon se zagrejao"</string>
- <string name="high_temp_notif_message" msgid="1277346543068257549">"Neke funkcije su ograničene dok se telefon ne ohladi.\nDodirnite za više informacija"</string>
- <string name="high_temp_dialog_message" msgid="3793606072661253968">"Telefon će automatski pokušati da se ohladi. I dalje ćete moći da koristite telefon, ali će sporije reagovati.\n\nKada se telefon ohladi, normalno će raditi."</string>
- <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Pogledajte upozorenja"</string>
- <string name="high_temp_alarm_title" msgid="8654754369605452169">"Isključite uređaj"</string>
- <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Uređaj se zagreva u blizini porta za punjenje. Ako je povezan sa punjačem ili USB opremom, isključite je i budite pažljivi jer i kabl može da bude vruć."</string>
- <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"Pogledajte upozorenja"</string>
- <string name="lockscreen_shortcut_left" msgid="1238765178956067599">"Leva prečica"</string>
- <string name="lockscreen_shortcut_right" msgid="4138414674531853719">"Desna prečica"</string>
- <string name="lockscreen_unlock_left" msgid="1417801334370269374">"I leva prečica otključava"</string>
- <string name="lockscreen_unlock_right" msgid="4658008735541075346">"I desna prečica otključava"</string>
- <string name="lockscreen_none" msgid="4710862479308909198">"Ništa"</string>
- <string name="tuner_launch_app" msgid="3906265365971743305">"Pokreni <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="tuner_other_apps" msgid="7767462881742291204">"Druge aplikacije"</string>
- <string name="tuner_circle" msgid="5270591778160525693">"Krug"</string>
- <string name="tuner_plus" msgid="4130366441154416484">"Plus"</string>
- <string name="tuner_minus" msgid="5258518368944598545">"Minus"</string>
- <string name="tuner_left" msgid="5758862558405684490">"Strelica ulevo"</string>
- <string name="tuner_right" msgid="8247571132790812149">"Strelica udesno"</string>
- <string name="tuner_menu" msgid="363690665924769420">"Meni"</string>
- <string name="tuner_app" msgid="6949280415826686972">"Aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="notification_channel_alerts" msgid="3385787053375150046">"Obaveštenja"</string>
- <string name="notification_channel_battery" msgid="9219995638046695106">"Baterija"</string>
- <string name="notification_channel_screenshot" msgid="7665814998932211997">"Snimci ekrana"</string>
- <string name="notification_channel_instant" msgid="7556135423486752680">"Instant aplikacije"</string>
- <string name="notification_channel_setup" msgid="7660580986090760350">"Podešavanje"</string>
- <string name="notification_channel_storage" msgid="2720725707628094977">"Memorijski prostor"</string>
- <string name="notification_channel_hints" msgid="7703783206000346876">"Saveti"</string>
- <string name="instant_apps" msgid="8337185853050247304">"Instant aplikacije"</string>
- <string name="instant_apps_title" msgid="8942706782103036910">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je pokrenuta"</string>
- <string name="instant_apps_message" msgid="6112428971833011754">"Aplikacija se otvorila bez instaliranja."</string>
- <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Aplikacija se otvorila bez instaliranja. Dodirnite da biste saznali više."</string>
- <string name="app_info" msgid="5153758994129963243">"Informacije o aplikaciji"</string>
- <string name="go_to_web" msgid="636673528981366511">"Idi na pregledač"</string>
- <string name="mobile_data" msgid="4564407557775397216">"Mobilni podaci"</string>
+ <string name="tuner_low_priority" msgid="8412666814123009820">"Прикажи иконе обавештења ниског приоритета"</string>
+ <string name="other" msgid="429768510980739978">"Друго"</string>
+ <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"уклонили плочицу"</string>
+ <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"додали плочицу на крај"</string>
+ <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Преместите плочицу"</string>
+ <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Додајте плочицу"</string>
+ <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Преместите на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string>
+ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додајте на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string>
+ <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција"</string>
+ <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плочица је додата"</string>
+ <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плочица је уклоњена"</string>
+ <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уређивач за Брза подешавања."</string>
+ <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Обавештења за <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отвори Подешавања."</string>
+ <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Отвори Брза подешавања."</string>
+ <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затвори Брза подешавања."</string>
+ <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Пријављени сте као <xliff:g id="ID_1">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"одабрали корисника"</string>
+ <string name="data_connection_no_internet" msgid="691058178914184544">"Нема интернета"</string>
+ <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Отвори подешавања за <xliff:g id="ID_1">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Измени редослед подешавања."</string>
+ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Мени дугмета за укључивање"</string>
+ <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. страна од <xliff:g id="ID_2">%2$d</xliff:g>"</string>
+ <string name="tuner_lock_screen" msgid="2267383813241144544">"Закључан екран"</string>
+ <string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон се искључио због топлоте"</string>
+ <string name="thermal_shutdown_message" msgid="6142269839066172984">"Телефон сада нормално ради.\nДодирните за више информација"</string>
+ <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефон је био преврућ, па се искључио да се охлади. Сада ради нормално.\n\nТелефон може превише да се угреје ако:\n • Користите апликације које захтевају пуно ресурса (нпр. видео игре, видео или апликације за навигацију)\n • Преузимате/отпремате велике датотеке\n • Користите телефон на високој температури"</string>
+ <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Погледајте упозорења"</string>
+ <string name="high_temp_title" msgid="2218333576838496100">"Телефон се загрејао"</string>
+ <string name="high_temp_notif_message" msgid="1277346543068257549">"Неке функције су ограничене док се телефон не охлади.\nДодирните за више информација"</string>
+ <string name="high_temp_dialog_message" msgid="3793606072661253968">"Телефон ће аутоматски покушати да се охлади. И даље ћете моћи да користите телефон, али ће спорије реаговати.\n\nКада се телефон охлади, нормално ће радити."</string>
+ <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Погледајте упозорења"</string>
+ <string name="high_temp_alarm_title" msgid="8654754369605452169">"Искључите уређај"</string>
+ <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Уређај се загрева у близини порта за пуњење. Ако је повезан са пуњачем или USB опремом, искључите је и будите пажљиви јер и кабл може да буде врућ."</string>
+ <string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"Погледајте упозорења"</string>
+ <string name="lockscreen_shortcut_left" msgid="1238765178956067599">"Лева пречица"</string>
+ <string name="lockscreen_shortcut_right" msgid="4138414674531853719">"Десна пречица"</string>
+ <string name="lockscreen_unlock_left" msgid="1417801334370269374">"И лева пречица откључава"</string>
+ <string name="lockscreen_unlock_right" msgid="4658008735541075346">"И десна пречица откључава"</string>
+ <string name="lockscreen_none" msgid="4710862479308909198">"Ништа"</string>
+ <string name="tuner_launch_app" msgid="3906265365971743305">"Покрени <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="tuner_other_apps" msgid="7767462881742291204">"Друге апликације"</string>
+ <string name="tuner_circle" msgid="5270591778160525693">"Круг"</string>
+ <string name="tuner_plus" msgid="4130366441154416484">"Плус"</string>
+ <string name="tuner_minus" msgid="5258518368944598545">"Минус"</string>
+ <string name="tuner_left" msgid="5758862558405684490">"Стрелица улево"</string>
+ <string name="tuner_right" msgid="8247571132790812149">"Стрелица удесно"</string>
+ <string name="tuner_menu" msgid="363690665924769420">"Мени"</string>
+ <string name="tuner_app" msgid="6949280415826686972">"Апликација <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="notification_channel_alerts" msgid="3385787053375150046">"Обавештења"</string>
+ <string name="notification_channel_battery" msgid="9219995638046695106">"Батерија"</string>
+ <string name="notification_channel_screenshot" msgid="7665814998932211997">"Снимци екрана"</string>
+ <string name="notification_channel_instant" msgid="7556135423486752680">"Инстант апликације"</string>
+ <string name="notification_channel_setup" msgid="7660580986090760350">"Подешавање"</string>
+ <string name="notification_channel_storage" msgid="2720725707628094977">"Меморијски простор"</string>
+ <string name="notification_channel_hints" msgid="7703783206000346876">"Савети"</string>
+ <string name="instant_apps" msgid="8337185853050247304">"Инстант апликације"</string>
+ <string name="instant_apps_title" msgid="8942706782103036910">"Апликација <xliff:g id="APP">%1$s</xliff:g> је покренута"</string>
+ <string name="instant_apps_message" msgid="6112428971833011754">"Апликација се отворила без инсталирања."</string>
+ <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Апликација се отворила без инсталирања. Додирните да бисте сазнали више."</string>
+ <string name="app_info" msgid="5153758994129963243">"Информације о апликацији"</string>
+ <string name="go_to_web" msgid="636673528981366511">"Иди на прегледач"</string>
+ <string name="mobile_data" msgid="4564407557775397216">"Мобилни подаци"</string>
<string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
- <string name="wifi_is_off" msgid="5389597396308001471">"WiFi je isključen"</string>
- <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
- <string name="dnd_is_off" msgid="3185706903793094463">"Režim Ne uznemiravaj je isključen"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>) je uključilo režim Ne uznemiravaj."</string>
- <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je uključila režim Ne uznemiravaj."</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automatsko pravilo ili aplikacija su uključili režim Ne uznemiravaj."</string>
- <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije pokrenute u pozadini"</string>
- <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
- <string name="mobile_data_disable_title" msgid="5366476131671617790">"Želite da isključite mobilne podatke?"</string>
- <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ili internetu preko mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo preko WiFi veze."</string>
- <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"mobilni operater"</string>
- <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Želite da se vratite na mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>?"</string>
- <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Mobilni podaci se neće automatski promeniti na osnovu dostupnosti"</string>
- <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Ne, hvala"</string>
- <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Da, pređi"</string>
- <string name="touch_filtered_warning" msgid="8119511393338714836">"Podešavanja ne mogu da verifikuju vaš odgovor jer aplikacija skriva zahtev za dozvolu."</string>
- <string name="slice_permission_title" msgid="3262615140094151017">"Želite li da dozvolite aplikaciji <xliff:g id="APP_0">%1$s</xliff:g> da prikazuje isečke iz aplikacije <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
- <string name="slice_permission_text_1" msgid="6675965177075443714">"– Može da čita podatke iz aplikacije <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="slice_permission_text_2" msgid="6758906940360746983">"– Može da obavlja radnje u aplikaciji <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="slice_permission_checkbox" msgid="4242888137592298523">"Dozvolite aplikaciji <xliff:g id="APP">%1$s</xliff:g> da prikazuje isečke iz bilo koje aplikacije"</string>
- <string name="slice_permission_allow" msgid="6340449521277951123">"Dozvoli"</string>
- <string name="slice_permission_deny" msgid="6870256451658176895">"Odbij"</string>
- <string name="auto_saver_title" msgid="6873691178754086596">"Dodirnite da biste napravili raspored za uštedu baterije"</string>
- <string name="auto_saver_text" msgid="3214960308353838764">"Uključite ako će baterija verovatno da se isprazni"</string>
- <string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string>
- <string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji SysUI mem."</string>
- <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"U upotrebi"</string>
- <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="wifi_is_off" msgid="5389597396308001471">"WiFi је искључен"</string>
+ <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth је искључен"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"Режим Не узнемиравај је искључен"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
+ <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Аутоматско правило (<xliff:g id="ID_1">%s</xliff:g>) је укључило режим Не узнемиравај."</string>
+ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апликација (<xliff:g id="ID_1">%s</xliff:g>) је укључила режим Не узнемиравај."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Аутоматско правило или апликација су укључили режим Не узнемиравај."</string>
+ <string name="running_foreground_services_title" msgid="5137313173431186685">"Апликације покренуте у позадини"</string>
+ <string name="running_foreground_services_msg" msgid="3009459259222695385">"Додирните за детаље о батерији и потрошњи података"</string>
+ <string name="mobile_data_disable_title" msgid="5366476131671617790">"Желите да искључите мобилне податке?"</string>
+ <string name="mobile_data_disable_message" msgid="8604966027899770415">"Нећете имати приступ подацима или интернету преко мобилног оператера <xliff:g id="CARRIER">%s</xliff:g>. Интернет ће бити доступан само преко WiFi везе."</string>
+ <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"мобилни оператер"</string>
+ <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Желите да се вратите на мобилног оператера <xliff:g id="CARRIER">%s</xliff:g>?"</string>
+ <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Мобилни подаци се неће аутоматски променити на основу доступности"</string>
+ <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Не, хвала"</string>
+ <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Да, пређи"</string>
+ <string name="touch_filtered_warning" msgid="8119511393338714836">"Подешавања не могу да верификују ваш одговор јер апликација скрива захтев за дозволу."</string>
+ <string name="slice_permission_title" msgid="3262615140094151017">"Желите ли да дозволите апликацији <xliff:g id="APP_0">%1$s</xliff:g> да приказује исечке из апликације <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
+ <string name="slice_permission_text_1" msgid="6675965177075443714">"– Може да чита податке из апликације <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="slice_permission_text_2" msgid="6758906940360746983">"– Може да обавља радње у апликацији <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="slice_permission_checkbox" msgid="4242888137592298523">"Дозволите апликацији <xliff:g id="APP">%1$s</xliff:g> да приказује исечке из било које апликације"</string>
+ <string name="slice_permission_allow" msgid="6340449521277951123">"Дозволи"</string>
+ <string name="slice_permission_deny" msgid="6870256451658176895">"Одбиј"</string>
+ <string name="auto_saver_title" msgid="6873691178754086596">"Додирните да бисте направили распоред за уштеду батерије"</string>
+ <string name="auto_saver_text" msgid="3214960308353838764">"Укључите ако ће батерија вероватно да се испразни"</string>
+ <string name="no_auto_saver_action" msgid="7467924389609773835">"Не, хвала"</string>
+ <string name="heap_dump_tile_name" msgid="2464189856478823046">"Издвоји SysUI мем."</string>
+ <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"У употреби"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликације користе <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
- <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
- <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Koristi: <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
- <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Nedavno koristio/la <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
- <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(posao)"</string>
- <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string>
- <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(preko: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Користи: <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Недавно користио/ла <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(посао)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонски позив"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(преко: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
<string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
<string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
- <string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
- <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
- <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
- <string name="privacy_type_media_projection" msgid="8136723828804251547">"snimanje ekrana"</string>
- <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
- <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string>
- <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećanje"</string>
- <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećanje"</string>
- <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Uvećajte"</string>
- <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Umanjite"</string>
- <string name="accessibility_control_move_up" msgid="6622825494014720136">"Pomerite nagore"</string>
- <string name="accessibility_control_move_down" msgid="5390922476900974512">"Pomerite nadole"</string>
- <string name="accessibility_control_move_left" msgid="8156206978511401995">"Pomerite nalevo"</string>
- <string name="accessibility_control_move_right" msgid="8926821093629582888">"Pomerite nadesno"</string>
- <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prelazak na drugi režim uvećanja"</string>
- <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećajte ceo ekran"</string>
- <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećajte deo ekrana"</string>
- <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Pređi"</string>
- <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Dodirnite za funkcije pristupačnosti. Prilagodite ili zamenite ovo dugme u Podešavanjima.\n\n"<annotation id="link">"Podešavanja"</annotation></string>
- <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Pomerite dugme do ivice da biste ga privremeno sakrili"</string>
- <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Premesti gore levo"</string>
- <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Premesti gore desno"</string>
- <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"Premesti dole levo"</string>
- <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Premesti dole desno"</string>
- <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Premesti do ivice i sakrij"</string>
- <string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Premesti izvan ivice i prikaži"</string>
- <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"uključite/isključite"</string>
- <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
- <string name="controls_providers_title" msgid="6879775889857085056">"Odaberite aplikaciju za dodavanje kontrola"</string>
- <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrola je dodata.}one{# kontrola je dodata.}few{# kontrole su dodate.}other{# kontrola je dodato.}}"</string>
- <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
- <string name="accessibility_control_favorite" msgid="8694362691985545985">"Označeno je kao omiljeno"</string>
- <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Označeno je kao omiljeno, <xliff:g id="NUMBER">%d</xliff:g>. pozicija"</string>
- <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno je iz omiljenih"</string>
- <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"označili kao omiljeno"</string>
- <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"uklonili iz omiljenih"</string>
- <string name="accessibility_control_move" msgid="8980344493796647792">"Premestite na <xliff:g id="NUMBER">%d</xliff:g>. poziciju"</string>
- <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrole"</string>
- <string name="controls_favorite_subtitle" msgid="6481675111056961083">"Odaberite kontrole da biste im pristupili iz Brzih podešavanja"</string>
- <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Zadržite i prevucite da biste promenili raspored kontrola"</string>
- <string name="controls_favorite_removed" msgid="5276978408529217272">"Sve kontrole su uklonjene"</string>
- <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Promene nisu sačuvane"</string>
- <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Pogledajte druge aplikacije"</string>
- <string name="controls_favorite_load_error" msgid="5126216176144877419">"Učitavanje kontrola nije uspelo. Pogledajte aplikaciju <xliff:g id="APP">%s</xliff:g> da biste se uverili da se podešavanja aplikacije nisu promenila."</string>
- <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatibilne kontrole nisu dostupne"</string>
- <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Drugo"</string>
- <string name="controls_dialog_title" msgid="2343565267424406202">"Dodajte u kontrole uređaja"</string>
- <string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
- <string name="controls_dialog_message" msgid="342066938390663844">"Predlaže <xliff:g id="APP">%s</xliff:g>"</string>
- <string name="controls_tile_locked" msgid="731547768182831938">"Uređaj je zaključan"</string>
- <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Želite li da prikazujete i kontrolišete uređaje sa zaključanog ekrana?"</string>
- <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Možete da dodate kontrole za spoljne uređaje na zaključani ekran.\n\nAplikacija na uređaju može da vam omogući da kontrolišete neke uređaje bez otključavanja telefona ili tableta.\n\nTo možete da promenite kad god želite u Podešavanjima."</string>
- <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Želite li da kontrolišete uređaje sa zaključanog ekrana?"</string>
- <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Neke uređaje možete da kontrolišete bez otključavanja telefona ili tableta.\n\nAplikacija na uređaju određuje koji uređaji mogu da se kontrolišu na ovaj način."</string>
- <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, hvala"</string>
- <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Da"</string>
- <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string>
- <string name="controls_pin_verify" msgid="3452778292918877662">"Verifikujte: <xliff:g id="DEVICE">%s</xliff:g>"</string>
- <string name="controls_pin_wrong" msgid="6162694056042164211">"Pogrešan PIN"</string>
- <string name="controls_pin_instructions" msgid="6363309783822475238">"Unesite PIN"</string>
- <string name="controls_pin_instructions_retry" msgid="1566667581012131046">"Probajte drugi PIN"</string>
- <string name="controls_confirmation_message" msgid="7744104992609594859">"Potvrdite promenu za: <xliff:g id="DEVICE">%s</xliff:g>"</string>
- <string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da biste videli još"</string>
- <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavaju se preporuke"</string>
- <string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
- <string name="controls_media_close_session" msgid="4780485355795635052">"Želite li da sakrijete ovu kontrolu za medije za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
- <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuelna sesija medija ne može da bude sakrivena."</string>
- <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
- <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
- <string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string>
- <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se pušta iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
- <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
- <string name="controls_media_button_play" msgid="2705068099607410633">"Pusti"</string>
- <string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziraj"</string>
- <string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodna pesma"</string>
- <string name="controls_media_button_next" msgid="6662636627525947610">"Sledeća pesma"</string>
- <string name="controls_media_button_connecting" msgid="3138354625847598095">"Povezuje se"</string>
- <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Pusti"</string>
- <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvorite <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
- <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
- <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
- <string name="media_transfer_undo" msgid="1895606387620728736">"Opozovi"</string>
- <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite da biste puštali muziku na: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
- <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da biste na njemu puštali"</string>
- <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Pušta se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
- <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo je do greške. Probajte ponovo."</string>
- <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string>
- <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
- <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"Pristupanje uređaju <xliff:g id="DEVICE">%1$s</xliff:g> nije uspelo. Pogledajte aplikaciju <xliff:g id="APPLICATION">%2$s</xliff:g> da biste se uverili da je kontrola još uvek dostupna i da se podešavanja aplikacije nisu promenila."</string>
- <string name="controls_open_app" msgid="483650971094300141">"Otvori aplikaciju"</string>
- <string name="controls_error_generic" msgid="352500456918362905">"Učitavanje statusa nije uspelo"</string>
- <string name="controls_error_failed" msgid="960228639198558525">"Greška. Probajte ponovo"</string>
- <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj kontrole"</string>
- <string name="controls_menu_edit" msgid="890623986951347062">"Izmeni kontrole"</string>
- <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodajte izlaze"</string>
- <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string>
- <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Izabran je 1 uređaj"</string>
- <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Izabranih uređaja: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
- <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
- <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Prebacivanje nije uspelo. Probajte ponovo."</string>
- <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Povežite uređaj"</string>
- <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste prebacivali ovu sesiju, otvorite aplikaciju."</string>
- <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
- <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi prebacivanje"</string>
- <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupni uređaji za audio izlaz."</string>
- <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Zvuk"</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"локацију"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
+ <string name="privacy_type_media_projection" msgid="8136723828804251547">"снимање екрана"</string>
+ <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслова"</string>
+ <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string>
+ <string name="magnification_window_title" msgid="4863914360847258333">"Прозор за увећање"</string>
+ <string name="magnification_controls_title" msgid="8421106606708891519">"Контроле прозора за увећање"</string>
+ <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Увећајте"</string>
+ <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Умањите"</string>
+ <string name="accessibility_control_move_up" msgid="6622825494014720136">"Померите нагоре"</string>
+ <string name="accessibility_control_move_down" msgid="5390922476900974512">"Померите надоле"</string>
+ <string name="accessibility_control_move_left" msgid="8156206978511401995">"Померите налево"</string>
+ <string name="accessibility_control_move_right" msgid="8926821093629582888">"Померите надесно"</string>
+ <string name="magnification_mode_switch_description" msgid="2698364322069934733">"Прелазак на други режим увећања"</string>
+ <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увећајте цео екран"</string>
+ <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увећајте део екрана"</string>
+ <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Пређи"</string>
+ <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Додирните за функције приступачности. Прилагодите или замените ово дугме у Подешавањима.\n\n"<annotation id="link">"Подешавања"</annotation></string>
+ <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Померите дугме до ивице да бисте га привремено сакрили"</string>
+ <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Премести горе лево"</string>
+ <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Премести горе десно"</string>
+ <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"Премести доле лево"</string>
+ <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Премести доле десно"</string>
+ <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Премести до ивице и сакриј"</string>
+ <string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Премести изван ивице и прикажи"</string>
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"укључите/искључите"</string>
+ <string name="quick_controls_title" msgid="6839108006171302273">"Контроле уређаја"</string>
+ <string name="controls_providers_title" msgid="6879775889857085056">"Одаберите апликацију за додавање контрола"</string>
+ <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# контрола је додата.}one{# контрола је додата.}few{# контроле су додате.}other{# контрола је додато.}}"</string>
+ <string name="controls_removed" msgid="3731789252222856959">"Уклоњено"</string>
+ <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено је као омиљено"</string>
+ <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено је као омиљено, <xliff:g id="NUMBER">%d</xliff:g>. позиција"</string>
+ <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Уклоњено је из омиљених"</string>
+ <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"означили као омиљено"</string>
+ <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"уклонили из омиљених"</string>
+ <string name="accessibility_control_move" msgid="8980344493796647792">"Преместите на <xliff:g id="NUMBER">%d</xliff:g>. позицију"</string>
+ <string name="controls_favorite_default_title" msgid="967742178688938137">"Контроле"</string>
+ <string name="controls_favorite_subtitle" msgid="6481675111056961083">"Одаберите контроле да бисте им приступили из Брзих подешавања"</string>
+ <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Задржите и превуците да бисте променили распоред контрола"</string>
+ <string name="controls_favorite_removed" msgid="5276978408529217272">"Све контроле су уклоњене"</string>
+ <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Промене нису сачуване"</string>
+ <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Погледајте друге апликације"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Учитавање контрола није успело. Погледајте апликацију <xliff:g id="APP">%s</xliff:g> да бисте се уверили да се подешавања апликације нису променила."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Компатибилне контроле нису доступне"</string>
+ <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Друго"</string>
+ <string name="controls_dialog_title" msgid="2343565267424406202">"Додајте у контроле уређаја"</string>
+ <string name="controls_dialog_ok" msgid="2770230012857881822">"Додај"</string>
+ <string name="controls_dialog_message" msgid="342066938390663844">"Предлаже <xliff:g id="APP">%s</xliff:g>"</string>
+ <string name="controls_tile_locked" msgid="731547768182831938">"Уређај је закључан"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Желите ли да приказујете и контролишете уређаје са закључаног екрана?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Можете да додате контроле за спољне уређаје на закључани екран.\n\nАпликација на уређају може да вам омогући да контролишете неке уређаје без откључавања телефона или таблета.\n\nТо можете да промените кад год желите у Подешавањима."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Желите ли да контролишете уређаје са закључаног екрана?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"Неке уређаје можете да контролишете без откључавања телефона или таблета.\n\nАпликација на уређају одређује који уређаји могу да се контролишу на овај начин."</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Не, хвала"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Да"</string>
+ <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN садржи слова или симболе"</string>
+ <string name="controls_pin_verify" msgid="3452778292918877662">"Верификујте: <xliff:g id="DEVICE">%s</xliff:g>"</string>
+ <string name="controls_pin_wrong" msgid="6162694056042164211">"Погрешан PIN"</string>
+ <string name="controls_pin_instructions" msgid="6363309783822475238">"Унесите PIN"</string>
+ <string name="controls_pin_instructions_retry" msgid="1566667581012131046">"Пробајте други PIN"</string>
+ <string name="controls_confirmation_message" msgid="7744104992609594859">"Потврдите промену за: <xliff:g id="DEVICE">%s</xliff:g>"</string>
+ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Превуците да бисте видели још"</string>
+ <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Учитавају се препоруке"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Медији"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Желите ли да сакријете ову контролу за медије за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"Актуелна сесија медија не може да буде сакривена."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сакриј"</string>
+ <string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string>
+ <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се пушта из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
+ <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_button_play" msgid="2705068099607410633">"Пусти"</string>
+ <string name="controls_media_button_pause" msgid="8614887780950376258">"Паузирај"</string>
+ <string name="controls_media_button_prev" msgid="8126822360056482970">"Претходна песма"</string>
+ <string name="controls_media_button_next" msgid="6662636627525947610">"Следећа песма"</string>
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Повезује се"</string>
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Пусти"</string>
+ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Отворите <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
+ <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
+ <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+ <string name="media_transfer_undo" msgid="1895606387620728736">"Опозови"</string>
+ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближите да бисте пуштали музику на: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближите се уређају <xliff:g id="DEVICENAME">%1$s</xliff:g> да бисте на њему пуштали"</string>
+ <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пушта се на уређају <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Дошло је до грешке. Пробајте поново."</string>
+ <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Контрола није доступна"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Приступање уређају <xliff:g id="DEVICE">%1$s</xliff:g> није успело. Погледајте апликацију <xliff:g id="APPLICATION">%2$s</xliff:g> да бисте се уверили да је контрола још увек доступна и да се подешавања апликације нису променила."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Отвори апликацију"</string>
+ <string name="controls_error_generic" msgid="352500456918362905">"Учитавање статуса није успело"</string>
+ <string name="controls_error_failed" msgid="960228639198558525">"Грешка. Пробајте поново"</string>
+ <string name="controls_menu_add" msgid="4447246119229920050">"Додај контроле"</string>
+ <string name="controls_menu_edit" msgid="890623986951347062">"Измени контроле"</string>
+ <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Додајте излазе"</string>
+ <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string>
+ <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Изабран је 1 уређај"</string>
+ <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Изабраних уређаја: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(веза је прекинута)"</string>
+ <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Пребацивање није успело. Пробајте поново."</string>
+ <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Повежите уређај"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Да бисте пребацивали ову сесију, отворите апликацију."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
+ <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Заустави пребацивање"</string>
+ <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Доступни уређаји за аудио излаз."</string>
+ <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Звук"</string>
<string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
- <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcioniše emitovanje"</string>
- <string name="media_output_broadcast" msgid="3555580945878071543">"Emitovanje"</string>
- <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ljudi u blizini sa kompatibilnim Bluetooth uređajima mogu da slušaju medijski sadržaj koji emitujete"</string>
- <string name="media_output_broadcasting_message" msgid="4150299923404886073">"Da bi slušali emitovanje, ljudi u blizini sa kompatibilnim Bluetooth uređajima mogu da skeniraju QR kôd ili da koriste naziv i lozinku emitovanja"</string>
- <string name="media_output_broadcast_name" msgid="8786127091542624618">"Naziv emitovanja"</string>
- <string name="media_output_broadcast_code" msgid="870795639644728542">"Lozinka"</string>
- <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Sačuvaj"</string>
- <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pokreće se…"</string>
- <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitovanje nije uspelo"</string>
- <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Čuvanje nije uspelo. Probajte ponovo."</string>
- <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Čuvanje nije uspelo."</string>
- <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
- <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
- <string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
- <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za konverzaciju"</string>
- <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite konverzaciju da biste je dodali na početni ekran"</string>
- <string name="no_conversations_text" msgid="5354115541282395015">"Nedavne konverzacije će se prikazati ovde"</string>
- <string name="priority_conversations" msgid="3967482288896653039">"Prioritetne konverzacije"</string>
- <string name="recent_conversations" msgid="8531874684782574622">"Nedavne konverzacije"</string>
- <string name="days_timestamp" msgid="5821854736213214331">"Pre <xliff:g id="DURATION">%1$s</xliff:g> dana"</string>
- <string name="one_week_timestamp" msgid="4925600765473875590">"Pre nedelju dana"</string>
- <string name="two_weeks_timestamp" msgid="9111801081871962155">"Pre 2 nedelje"</string>
- <string name="over_one_week_timestamp" msgid="3770560704420807142">"Pre više od nedelju dana"</string>
- <string name="over_two_weeks_timestamp" msgid="6300507859007874050">"Pre više od 2 nedelje"</string>
- <string name="birthday_status" msgid="2596961629465396761">"Rođendan"</string>
- <string name="birthday_status_content_description" msgid="682836371128282925">"<xliff:g id="NAME">%1$s</xliff:g> danas slavi rođendan"</string>
- <string name="upcoming_birthday_status" msgid="2005452239256870351">"Rođendan je uskoro"</string>
- <string name="upcoming_birthday_status_content_description" msgid="2165036816803797148">"<xliff:g id="NAME">%1$s</xliff:g> uskoro slavi rođendan"</string>
- <string name="anniversary_status" msgid="1790034157507590838">"Godišnjica"</string>
- <string name="anniversary_status_content_description" msgid="8212171790843327442">"<xliff:g id="NAME">%1$s</xliff:g> danas slavi godišnjicu"</string>
- <string name="location_status" msgid="1294990572202541812">"Deli se lokacija"</string>
- <string name="location_status_content_description" msgid="2982386178160071305">"<xliff:g id="NAME">%1$s</xliff:g> deli lokaciju"</string>
- <string name="new_story_status" msgid="9012195158584846525">"Nova priča"</string>
- <string name="new_story_status_content_description" msgid="4963137422622516708">"<xliff:g id="NAME">%1$s</xliff:g> deli novu priču"</string>
- <string name="video_status" msgid="4548544654316843225">"Gleda se"</string>
- <string name="audio_status" msgid="4237055636967709208">"Sluša se"</string>
- <string name="game_status" msgid="1340694320630973259">"Igra se"</string>
- <string name="empty_user_name" msgid="3389155775773578300">"Prijatelji"</string>
- <string name="empty_status" msgid="5938893404951307749">"Ćaskamo večeras?"</string>
- <string name="status_before_loading" msgid="1500477307859631381">"Sadržaj će se uskoro pojaviti"</string>
- <string name="missed_call" msgid="4228016077700161689">"Propušten poziv"</string>
+ <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционише емитовање"</string>
+ <string name="media_output_broadcast" msgid="3555580945878071543">"Емитовање"</string>
+ <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Људи у близини са компатибилним Bluetooth уређајима могу да слушају медијски садржај који емитујете"</string>
+ <string name="media_output_broadcasting_message" msgid="4150299923404886073">"Да би слушали емитовање, људи у близини са компатибилним Bluetooth уређајима могу да скенирају QR кôд или да користе назив и лозинку емитовања"</string>
+ <string name="media_output_broadcast_name" msgid="8786127091542624618">"Назив емитовања"</string>
+ <string name="media_output_broadcast_code" msgid="870795639644728542">"Лозинка"</string>
+ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сачувај"</string>
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Покреће се…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Емитовање није успело"</string>
+ <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Чување није успело. Пробајте поново."</string>
+ <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Чување није успело."</string>
+ <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
+ <string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
+ <string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
+ <string name="select_conversation_title" msgid="6716364118095089519">"Виџети за конверзацију"</string>
+ <string name="select_conversation_text" msgid="3376048251434956013">"Додирните конверзацију да бисте је додали на почетни екран"</string>
+ <string name="no_conversations_text" msgid="5354115541282395015">"Недавне конверзације ће се приказати овде"</string>
+ <string name="priority_conversations" msgid="3967482288896653039">"Приоритетне конверзације"</string>
+ <string name="recent_conversations" msgid="8531874684782574622">"Недавне конверзације"</string>
+ <string name="days_timestamp" msgid="5821854736213214331">"Пре <xliff:g id="DURATION">%1$s</xliff:g> дана"</string>
+ <string name="one_week_timestamp" msgid="4925600765473875590">"Пре недељу дана"</string>
+ <string name="two_weeks_timestamp" msgid="9111801081871962155">"Пре 2 недеље"</string>
+ <string name="over_one_week_timestamp" msgid="3770560704420807142">"Пре више од недељу дана"</string>
+ <string name="over_two_weeks_timestamp" msgid="6300507859007874050">"Пре више од 2 недеље"</string>
+ <string name="birthday_status" msgid="2596961629465396761">"Рођендан"</string>
+ <string name="birthday_status_content_description" msgid="682836371128282925">"<xliff:g id="NAME">%1$s</xliff:g> данас слави рођендан"</string>
+ <string name="upcoming_birthday_status" msgid="2005452239256870351">"Рођендан је ускоро"</string>
+ <string name="upcoming_birthday_status_content_description" msgid="2165036816803797148">"<xliff:g id="NAME">%1$s</xliff:g> ускоро слави рођендан"</string>
+ <string name="anniversary_status" msgid="1790034157507590838">"Годишњица"</string>
+ <string name="anniversary_status_content_description" msgid="8212171790843327442">"<xliff:g id="NAME">%1$s</xliff:g> данас слави годишњицу"</string>
+ <string name="location_status" msgid="1294990572202541812">"Дели се локација"</string>
+ <string name="location_status_content_description" msgid="2982386178160071305">"<xliff:g id="NAME">%1$s</xliff:g> дели локацију"</string>
+ <string name="new_story_status" msgid="9012195158584846525">"Нова прича"</string>
+ <string name="new_story_status_content_description" msgid="4963137422622516708">"<xliff:g id="NAME">%1$s</xliff:g> дели нову причу"</string>
+ <string name="video_status" msgid="4548544654316843225">"Гледа се"</string>
+ <string name="audio_status" msgid="4237055636967709208">"Слуша се"</string>
+ <string name="game_status" msgid="1340694320630973259">"Игра се"</string>
+ <string name="empty_user_name" msgid="3389155775773578300">"Пријатељи"</string>
+ <string name="empty_status" msgid="5938893404951307749">"Ћаскамо вечерас?"</string>
+ <string name="status_before_loading" msgid="1500477307859631381">"Садржај ће се ускоро појавити"</string>
+ <string name="missed_call" msgid="4228016077700161689">"Пропуштен позив"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
- <string name="people_tile_description" msgid="8154966188085545556">"Pogledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string>
- <string name="people_tile_title" msgid="6589377493334871272">"Konverzacija"</string>
- <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirano režimom Ne uznemiravaj"</string>
- <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
- <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> šalje sliku"</string>
- <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ima ažuriranje statusa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
- <string name="person_available" msgid="2318599327472755472">"Dostupno"</string>
- <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem sa očitavanjem merača baterije"</string>
- <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
- <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nije podešen"</string>
- <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor za otisak prsta"</string>
- <string name="accessibility_authenticate_hint" msgid="798914151813205721">"potvrdite identitet"</string>
- <string name="accessibility_enter_hint" msgid="2617864063504824834">"unesite uređaj"</string>
- <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string>
- <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Potrebna je potvrda identiteta. Dodirnite senzor za otisak prsta da biste potvrdili identitet."</string>
- <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Aktuelni telefonski poziv"</string>
- <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilni podaci"</string>
+ <string name="people_tile_description" msgid="8154966188085545556">"Погледајте недавне поруке, пропуштене позиве и ажурирања статуса"</string>
+ <string name="people_tile_title" msgid="6589377493334871272">"Конверзација"</string>
+ <string name="paused_by_dnd" msgid="7856941866433556428">"Паузирано режимом Не узнемиравај"</string>
+ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> је послао/ла поруку: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
+ <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> шаље слику"</string>
+ <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има ажурирање статуса: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Доступно"</string>
+ <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем са очитавањем мерача батерије"</string>
+ <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Додирните за више информација"</string>
+ <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Није подешен"</string>
+ <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отисак прста"</string>
+ <string name="accessibility_authenticate_hint" msgid="798914151813205721">"потврдите идентитет"</string>
+ <string name="accessibility_enter_hint" msgid="2617864063504824834">"унесите уређај"</string>
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Отворите помоћу отиска прста"</string>
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Потребна је потврда идентитета. Додирните сензор за отисак прста да бисте потврдили идентитет."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Актуелни телефонски позив"</string>
+ <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилни подаци"</string>
<string name="preference_summary_default_combination" msgid="8453246369903749670">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="NETWORKMODE">%2$s</xliff:g>"</string>
- <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string>
- <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string>
- <string name="mobile_data_poor_connection" msgid="819617772268371434">"Veza je loša"</string>
- <string name="mobile_data_off_summary" msgid="3663995422004150567">"Nije uspelo autom. povezivanje preko mob. podataka"</string>
- <string name="mobile_data_no_connection" msgid="1713872434869947377">"Veza nije uspostavljena"</string>
- <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Nije dostupna nijedna druga mreža"</string>
- <string name="all_network_unavailable" msgid="4112774339909373349">"Nema dostupnih mreža"</string>
+ <string name="mobile_data_connection_active" msgid="944490013299018227">"Повезано"</string>
+ <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Привремено повезано"</string>
+ <string name="mobile_data_poor_connection" msgid="819617772268371434">"Веза је лоша"</string>
+ <string name="mobile_data_off_summary" msgid="3663995422004150567">"Није успело аутом. повезивање преко моб. података"</string>
+ <string name="mobile_data_no_connection" msgid="1713872434869947377">"Веза није успостављена"</string>
+ <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Није доступна ниједна друга мрежа"</string>
+ <string name="all_network_unavailable" msgid="4112774339909373349">"Нема доступних мрежа"</string>
<string name="turn_on_wifi" msgid="1308379840799281023">"WiFi"</string>
- <string name="tap_a_network_to_connect" msgid="1565073330852369558">"Dodirnite mrežu da biste se povezali"</string>
- <string name="unlock_to_view_networks" msgid="5072880496312015676">"Otključajte da biste videli mreže"</string>
- <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Traže se mreže…"</string>
- <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Povezivanje sa mrežom nije uspelo"</string>
- <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"WiFi trenutno ne može da se automatski poveže"</string>
- <string name="see_all_networks" msgid="3773666844913168122">"Pogledajte sve"</string>
- <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Da biste promenili mrežu, prekinite eternet vezu"</string>
- <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Radi boljeg doživljaja uređaja, aplikacije i usluge i dalje mogu da traže WiFi mreže u bilo kom trenutku, čak i kada je WiFi isključen. To možete da promenite u podešavanjima WiFi skeniranja. "<annotation id="link">"Promenite"</annotation></string>
- <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Isključite režim rada u avionu"</string>
- <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> želi da doda sledeću pločicu u Brza podešavanja"</string>
- <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj pločicu"</string>
- <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne dodaj pločicu"</string>
- <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Izaberite korisnika"</string>
- <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikacija je aktivna}one{# aplikacija je aktivna}few{# aplikacije su aktivne}other{# aplikacija je aktivno}}"</string>
- <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
- <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
- <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ove aplikacije su aktivne i rade čak i kada ih ne koristite. To im poboljšava funkcionalnost, ali može da utiče i na trajanje baterije."</string>
- <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
- <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
- <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Gotovo"</string>
- <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano je"</string>
- <string name="clipboard_edit_source" msgid="9156488177277788029">"Od: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="clipboard_dismiss_description" msgid="3335990369850165486">"Odbaci kopirani tekst"</string>
- <string name="clipboard_edit_text_description" msgid="805254383912962103">"Izmenite kopirani tekst"</string>
- <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Izmenite kopiranu sliku"</string>
- <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji na uređaj u blizini"</string>
- <string name="clipboard_text_hidden" msgid="7926899867471812305">"Dodirnite da biste pregledali"</string>
- <string name="clipboard_text_copied" msgid="5100836834278976679">"Tekst je kopiran"</string>
- <string name="clipboard_image_copied" msgid="3793365360174328722">"Slika je kopirana"</string>
- <string name="clipboard_content_copied" msgid="144452398567828145">"Sadržaj je kopiran"</string>
- <string name="clipboard_editor" msgid="2971197550401892843">"Uređivač privremene memorije"</string>
- <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Privremena memorija"</string>
- <string name="clipboard_image_preview" msgid="2156475174343538128">"Pregled slike"</string>
- <string name="clipboard_edit" msgid="4500155216174011640">"izmenite"</string>
- <string name="add" msgid="81036585205287996">"Dodaj"</string>
- <string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obaveštenje ne podržava prevlačenje na podeljeni ekran."</string>
- <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi nije dostupan"</string>
- <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni režim"</string>
- <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je podešen"</string>
- <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera je isključena"</string>
- <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon je isključen"</string>
- <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
- <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obaveštenje}one{# obaveštenje}few{# obaveštenja}other{# obaveštenja}}"</string>
+ <string name="tap_a_network_to_connect" msgid="1565073330852369558">"Додирните мрежу да бисте се повезали"</string>
+ <string name="unlock_to_view_networks" msgid="5072880496312015676">"Откључајте да бисте видели мреже"</string>
+ <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Траже се мреже…"</string>
+ <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Повезивање са мрежом није успело"</string>
+ <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"WiFi тренутно не може да се аутоматски повеже"</string>
+ <string name="see_all_networks" msgid="3773666844913168122">"Погледајте све"</string>
+ <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Да бисте променили мрежу, прекините етернет везу"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Ради бољег доживљаја уређаја, апликације и услуге и даље могу да траже WiFi мреже у било ком тренутку, чак и када је WiFi искључен. То можете да промените у подешавањима WiFi скенирања. "<annotation id="link">"Промените"</annotation></string>
+ <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Искључите режим рада у авиону"</string>
+ <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> жели да дода следећу плочицу у Брза подешавања"</string>
+ <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Додај плочицу"</string>
+ <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Не додај плочицу"</string>
+ <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Изаберите корисника"</string>
+ <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# апликација је активна}one{# апликација је активна}few{# апликације су активне}other{# апликација је активно}}"</string>
+ <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нове информације"</string>
+ <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активне апликације"</string>
+ <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ове апликације су активне и раде чак и када их не користите. То им побољшава функционалност, али може да утиче и на трајање батерије."</string>
+ <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Заустави"</string>
+ <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Заустављено"</string>
+ <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Готово"</string>
+ <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано је"</string>
+ <string name="clipboard_edit_source" msgid="9156488177277788029">"Од: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
+ <string name="clipboard_dismiss_description" msgid="3335990369850165486">"Одбаци копирани текст"</string>
+ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Измените копирани текст"</string>
+ <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Измените копирану слику"</string>
+ <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Пошаљи на уређај у близини"</string>
+ <string name="clipboard_text_hidden" msgid="7926899867471812305">"Додирните да бисте прегледали"</string>
+ <string name="clipboard_text_copied" msgid="5100836834278976679">"Текст је копиран"</string>
+ <string name="clipboard_image_copied" msgid="3793365360174328722">"Слика је копирана"</string>
+ <string name="clipboard_content_copied" msgid="144452398567828145">"Садржај је копиран"</string>
+ <string name="clipboard_editor" msgid="2971197550401892843">"Уређивач привремене меморије"</string>
+ <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Привремена меморија"</string>
+ <string name="clipboard_image_preview" msgid="2156475174343538128">"Преглед слике"</string>
+ <string name="clipboard_edit" msgid="4500155216174011640">"измените"</string>
+ <string name="add" msgid="81036585205287996">"Додај"</string>
+ <string name="manage_users" msgid="1823875311934643849">"Управљаjте корисницима"</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"Ово обавештење не подржава превлачење на подељени екран."</string>
+ <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi није доступан"</string>
+ <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетни режим"</string>
+ <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Аларм је подешен"</string>
+ <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камера је искључена"</string>
+ <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Микрофон је искључен"</string>
+ <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон су искључени"</string>
+ <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# обавештење}one{# обавештење}few{# обавештења}other{# обавештења}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Pravljenje beležaka"</string>
- <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitovanje"</string>
- <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite da zaustavite emitovanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
- <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string>
- <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitujte aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
- <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promenite izlaz"</string>
- <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, d. MMM"</string>
- <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:min"</string>
- <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"č:min"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvorite: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Da biste dodali aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g> kao prečicu, uverite se:"</string>
- <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• da je aplikacija podešena"</string>
- <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• da je u Novčanik dodata barem jedna kartica"</string>
- <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• da ste instalirali aplikaciju za kameru"</string>
- <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• da je aplikacija podešena"</string>
- <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• da je dostupan barem jedan uređaj"</string>
- <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string>
- <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrnite"</string>
- <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon za bolji selfi"</string>
- <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Želite da obrnete na prednji ekran za bolji selfi?"</string>
- <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite zadnju kameru da biste snimili širu sliku sa višom rezolucijom."</string>
- <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ovaj ekran će se isključiti"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
+ <string name="note_task_button_label" msgid="8718616095800343136">"Прављење бележака"</string>
+ <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитовање"</string>
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Желите да зауставите емитовање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промените излаз"</string>
+ <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"с:мин"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ч:мин"</string>
+ <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворите: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
+ <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"Да бисте додали апликацију <xliff:g id="APPNAME">%1$s</xliff:g> као пречицу, уверите се:"</string>
+ <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• да је апликација подешена"</string>
+ <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• да је у Новчаник додата барем једна картица"</string>
+ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• да сте инсталирали апликацију за камеру"</string>
+ <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• да је апликација подешена"</string>
+ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• да је доступан барем један уређај"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
<skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
+ <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обрните"</string>
+ <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворите телефон за бољи селфи"</string>
+ <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Желите да обрнете на предњи екран за бољи селфи?"</string>
+ <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Користите задњу камеру да бисте снимили ширу слику са вишом резолуцијом."</string>
+ <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Овај екран ће се искључити"</b></string>
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Уређај на преклоп се отвара"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Уређај на преклоп се обрће"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
index 27e22d8..8ca1057 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -19,15 +19,15 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="notification_vpn_connected" msgid="3891023882833274730">"VPN je povezan"</string>
- <string name="notification_vpn_disconnected" msgid="7150747626448044843">"Veza sa VPN-om je prekinuta"</string>
- <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="tv_notification_panel_title" msgid="5311050946506276154">"Obaveštenja"</string>
- <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nema obaveštenja"</string>
- <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon snima"</string>
- <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera snima"</string>
- <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera i mikrofon snimaju"</string>
- <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Snimanje mikrofonom je zaustavljeno"</string>
- <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Snimanje kamerom je zaustavljeno"</string>
- <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Snimanje kamerom i mikrofonom je zaustavljeno"</string>
+ <string name="notification_vpn_connected" msgid="3891023882833274730">"VPN је повезан"</string>
+ <string name="notification_vpn_disconnected" msgid="7150747626448044843">"Веза са VPN-ом је прекинута"</string>
+ <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="tv_notification_panel_title" msgid="5311050946506276154">"Обавештења"</string>
+ <string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Нема обавештења"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон снима"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера снима"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера и микрофон снимају"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Снимање микрофоном је заустављено"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Снимање камером је заустављено"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Снимање камером и микрофоном је заустављено"</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index b69b064..dace491 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -32,148 +32,148 @@
<!-- no translation found for tile_states_default:1 (7086813178962737808) -->
<!-- no translation found for tile_states_default:2 (9192445505551219506) -->
<string-array name="tile_states_internet">
- <item msgid="5499482407653291407">"Nedostupno"</item>
- <item msgid="3048856902433862868">"Isključeno"</item>
- <item msgid="6877982264300789870">"Uključeno"</item>
+ <item msgid="5499482407653291407">"Недоступно"</item>
+ <item msgid="3048856902433862868">"Искључено"</item>
+ <item msgid="6877982264300789870">"Укључено"</item>
</string-array>
<string-array name="tile_states_wifi">
- <item msgid="8054147400538405410">"Nedostupno"</item>
- <item msgid="4293012229142257455">"Isključeno"</item>
- <item msgid="6221288736127914861">"Uključeno"</item>
+ <item msgid="8054147400538405410">"Недоступно"</item>
+ <item msgid="4293012229142257455">"Искључено"</item>
+ <item msgid="6221288736127914861">"Укључено"</item>
</string-array>
<string-array name="tile_states_cell">
- <item msgid="1235899788959500719">"Nedostupno"</item>
- <item msgid="2074416252859094119">"Isključeno"</item>
- <item msgid="287997784730044767">"Uključeno"</item>
+ <item msgid="1235899788959500719">"Недоступно"</item>
+ <item msgid="2074416252859094119">"Искључено"</item>
+ <item msgid="287997784730044767">"Укључено"</item>
</string-array>
<string-array name="tile_states_battery">
- <item msgid="6311253873330062961">"Nedostupno"</item>
- <item msgid="7838121007534579872">"Isključeno"</item>
- <item msgid="1578872232501319194">"Uključeno"</item>
+ <item msgid="6311253873330062961">"Недоступно"</item>
+ <item msgid="7838121007534579872">"Искључено"</item>
+ <item msgid="1578872232501319194">"Укључено"</item>
</string-array>
<string-array name="tile_states_dnd">
- <item msgid="467587075903158357">"Nedostupno"</item>
- <item msgid="5376619709702103243">"Isključeno"</item>
- <item msgid="4875147066469902392">"Uključeno"</item>
+ <item msgid="467587075903158357">"Недоступно"</item>
+ <item msgid="5376619709702103243">"Искључено"</item>
+ <item msgid="4875147066469902392">"Укључено"</item>
</string-array>
<string-array name="tile_states_flashlight">
- <item msgid="3465257127433353857">"Nedostupno"</item>
- <item msgid="5044688398303285224">"Isključeno"</item>
- <item msgid="8527389108867454098">"Uključeno"</item>
+ <item msgid="3465257127433353857">"Недоступно"</item>
+ <item msgid="5044688398303285224">"Искључено"</item>
+ <item msgid="8527389108867454098">"Укључено"</item>
</string-array>
<string-array name="tile_states_rotation">
- <item msgid="4578491772376121579">"Nedostupno"</item>
- <item msgid="5776427577477729185">"Isključeno"</item>
- <item msgid="7105052717007227415">"Uključeno"</item>
+ <item msgid="4578491772376121579">"Недоступно"</item>
+ <item msgid="5776427577477729185">"Искључено"</item>
+ <item msgid="7105052717007227415">"Укључено"</item>
</string-array>
<string-array name="tile_states_bt">
- <item msgid="5330252067413512277">"Nedostupno"</item>
- <item msgid="5315121904534729843">"Isključeno"</item>
- <item msgid="503679232285959074">"Uključeno"</item>
+ <item msgid="5330252067413512277">"Недоступно"</item>
+ <item msgid="5315121904534729843">"Искључено"</item>
+ <item msgid="503679232285959074">"Укључено"</item>
</string-array>
<string-array name="tile_states_airplane">
- <item msgid="1985366811411407764">"Nedostupno"</item>
- <item msgid="4801037224991420996">"Isključeno"</item>
- <item msgid="1982293347302546665">"Uključeno"</item>
+ <item msgid="1985366811411407764">"Недоступно"</item>
+ <item msgid="4801037224991420996">"Искључено"</item>
+ <item msgid="1982293347302546665">"Укључено"</item>
</string-array>
<string-array name="tile_states_location">
- <item msgid="3316542218706374405">"Nedostupno"</item>
- <item msgid="4813655083852587017">"Isključeno"</item>
- <item msgid="6744077414775180687">"Uključeno"</item>
+ <item msgid="3316542218706374405">"Недоступно"</item>
+ <item msgid="4813655083852587017">"Искључено"</item>
+ <item msgid="6744077414775180687">"Укључено"</item>
</string-array>
<string-array name="tile_states_hotspot">
- <item msgid="3145597331197351214">"Nedostupno"</item>
- <item msgid="5715725170633593906">"Isključeno"</item>
- <item msgid="2075645297847971154">"Uključeno"</item>
+ <item msgid="3145597331197351214">"Недоступно"</item>
+ <item msgid="5715725170633593906">"Искључено"</item>
+ <item msgid="2075645297847971154">"Укључено"</item>
</string-array>
<string-array name="tile_states_color_correction">
- <item msgid="2840507878437297682">"Nedostupno"</item>
- <item msgid="1909756493418256167">"Isključeno"</item>
- <item msgid="4531508423703413340">"Uključeno"</item>
+ <item msgid="2840507878437297682">"Недоступно"</item>
+ <item msgid="1909756493418256167">"Искључено"</item>
+ <item msgid="4531508423703413340">"Укључено"</item>
</string-array>
<string-array name="tile_states_inversion">
- <item msgid="3638187931191394628">"Nedostupno"</item>
- <item msgid="9103697205127645916">"Isključeno"</item>
- <item msgid="8067744885820618230">"Uključeno"</item>
+ <item msgid="3638187931191394628">"Недоступно"</item>
+ <item msgid="9103697205127645916">"Искључено"</item>
+ <item msgid="8067744885820618230">"Укључено"</item>
</string-array>
<string-array name="tile_states_saver">
- <item msgid="39714521631367660">"Nedostupno"</item>
- <item msgid="6983679487661600728">"Isključeno"</item>
- <item msgid="7520663805910678476">"Uključeno"</item>
+ <item msgid="39714521631367660">"Недоступно"</item>
+ <item msgid="6983679487661600728">"Искључено"</item>
+ <item msgid="7520663805910678476">"Укључено"</item>
</string-array>
<string-array name="tile_states_dark">
- <item msgid="2762596907080603047">"Nedostupno"</item>
- <item msgid="400477985171353">"Isključeno"</item>
- <item msgid="630890598801118771">"Uključeno"</item>
+ <item msgid="2762596907080603047">"Недоступно"</item>
+ <item msgid="400477985171353">"Искључено"</item>
+ <item msgid="630890598801118771">"Укључено"</item>
</string-array>
<string-array name="tile_states_work">
- <item msgid="389523503690414094">"Nedostupno"</item>
- <item msgid="8045580926543311193">"Isključeno"</item>
- <item msgid="4913460972266982499">"Uključeno"</item>
+ <item msgid="389523503690414094">"Недоступно"</item>
+ <item msgid="8045580926543311193">"Искључено"</item>
+ <item msgid="4913460972266982499">"Укључено"</item>
</string-array>
<string-array name="tile_states_cast">
- <item msgid="6032026038702435350">"Nedostupno"</item>
- <item msgid="1488620600954313499">"Isključeno"</item>
- <item msgid="588467578853244035">"Uključeno"</item>
+ <item msgid="6032026038702435350">"Недоступно"</item>
+ <item msgid="1488620600954313499">"Искључено"</item>
+ <item msgid="588467578853244035">"Укључено"</item>
</string-array>
<string-array name="tile_states_night">
- <item msgid="7857498964264855466">"Nedostupno"</item>
- <item msgid="2744885441164350155">"Isključeno"</item>
- <item msgid="151121227514952197">"Uključeno"</item>
+ <item msgid="7857498964264855466">"Недоступно"</item>
+ <item msgid="2744885441164350155">"Искључено"</item>
+ <item msgid="151121227514952197">"Укључено"</item>
</string-array>
<string-array name="tile_states_screenrecord">
- <item msgid="1085836626613341403">"Nedostupno"</item>
- <item msgid="8259411607272330225">"Isključeno"</item>
- <item msgid="578444932039713369">"Uključeno"</item>
+ <item msgid="1085836626613341403">"Недоступно"</item>
+ <item msgid="8259411607272330225">"Искључено"</item>
+ <item msgid="578444932039713369">"Укључено"</item>
</string-array>
<string-array name="tile_states_reverse">
- <item msgid="3574611556622963971">"Nedostupno"</item>
- <item msgid="8707481475312432575">"Isključeno"</item>
- <item msgid="8031106212477483874">"Uključeno"</item>
+ <item msgid="3574611556622963971">"Недоступно"</item>
+ <item msgid="8707481475312432575">"Искључено"</item>
+ <item msgid="8031106212477483874">"Укључено"</item>
</string-array>
<string-array name="tile_states_reduce_brightness">
- <item msgid="1839836132729571766">"Nedostupno"</item>
- <item msgid="4572245614982283078">"Isključeno"</item>
- <item msgid="6536448410252185664">"Uključeno"</item>
+ <item msgid="1839836132729571766">"Недоступно"</item>
+ <item msgid="4572245614982283078">"Искључено"</item>
+ <item msgid="6536448410252185664">"Укључено"</item>
</string-array>
<string-array name="tile_states_cameratoggle">
- <item msgid="6680671247180519913">"Nedostupno"</item>
- <item msgid="4765607635752003190">"Isključeno"</item>
- <item msgid="1697460731949649844">"Uključeno"</item>
+ <item msgid="6680671247180519913">"Недоступно"</item>
+ <item msgid="4765607635752003190">"Искључено"</item>
+ <item msgid="1697460731949649844">"Укључено"</item>
</string-array>
<string-array name="tile_states_mictoggle">
- <item msgid="6895831614067195493">"Nedostupno"</item>
- <item msgid="3296179158646568218">"Isključeno"</item>
- <item msgid="8998632451221157987">"Uključeno"</item>
+ <item msgid="6895831614067195493">"Недоступно"</item>
+ <item msgid="3296179158646568218">"Искључено"</item>
+ <item msgid="8998632451221157987">"Укључено"</item>
</string-array>
<string-array name="tile_states_controls">
- <item msgid="8199009425335668294">"Nedostupno"</item>
- <item msgid="4544919905196727508">"Isključeno"</item>
- <item msgid="3422023746567004609">"Uključeno"</item>
+ <item msgid="8199009425335668294">"Недоступно"</item>
+ <item msgid="4544919905196727508">"Искључено"</item>
+ <item msgid="3422023746567004609">"Укључено"</item>
</string-array>
<string-array name="tile_states_wallet">
- <item msgid="4177615438710836341">"Nedostupno"</item>
- <item msgid="7571394439974244289">"Isključeno"</item>
- <item msgid="6866424167599381915">"Uključeno"</item>
+ <item msgid="4177615438710836341">"Недоступно"</item>
+ <item msgid="7571394439974244289">"Искључено"</item>
+ <item msgid="6866424167599381915">"Укључено"</item>
</string-array>
<string-array name="tile_states_qr_code_scanner">
- <item msgid="7435143266149257618">"Nedostupno"</item>
- <item msgid="3301403109049256043">"Isključeno"</item>
- <item msgid="8878684975184010135">"Uključeno"</item>
+ <item msgid="7435143266149257618">"Недоступно"</item>
+ <item msgid="3301403109049256043">"Искључено"</item>
+ <item msgid="8878684975184010135">"Укључено"</item>
</string-array>
<string-array name="tile_states_alarm">
- <item msgid="4936533380177298776">"Nedostupno"</item>
- <item msgid="2710157085538036590">"Isključeno"</item>
- <item msgid="7809470840976856149">"Uključeno"</item>
+ <item msgid="4936533380177298776">"Недоступно"</item>
+ <item msgid="2710157085538036590">"Искључено"</item>
+ <item msgid="7809470840976856149">"Укључено"</item>
</string-array>
<string-array name="tile_states_onehanded">
- <item msgid="8189342855739930015">"Nedostupno"</item>
- <item msgid="146088982397753810">"Isključeno"</item>
- <item msgid="460891964396502657">"Uključeno"</item>
+ <item msgid="8189342855739930015">"Недоступно"</item>
+ <item msgid="146088982397753810">"Искључено"</item>
+ <item msgid="460891964396502657">"Укључено"</item>
</string-array>
<string-array name="tile_states_dream">
- <item msgid="6184819793571079513">"Nedostupno"</item>
- <item msgid="8014986104355098744">"Isključeno"</item>
- <item msgid="5966994759929723339">"Uključeno"</item>
+ <item msgid="6184819793571079513">"Недоступно"</item>
+ <item msgid="8014986104355098744">"Искључено"</item>
+ <item msgid="5966994759929723339">"Укључено"</item>
</string-array>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 31c9bcc..97a29bd 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -723,7 +723,7 @@
<string name="instant_apps_title" msgid="8942706782103036910">"Праграма \"<xliff:g id="APP">%1$s</xliff:g>\" запушчана"</string>
<string name="instant_apps_message" msgid="6112428971833011754">"Праграма адкрыта без усталёўкі."</string>
<string name="instant_apps_message_with_help" msgid="1816952263531203932">"Праграма адкрыта без усталёўкі. Націсніце, каб даведацца больш."</string>
- <string name="app_info" msgid="5153758994129963243">"Звесткі пра праграму"</string>
+ <string name="app_info" msgid="5153758994129963243">"Звесткі аб праграме"</string>
<string name="go_to_web" msgid="636673528981366511">"Перайсці ў браўзер"</string>
<string name="mobile_data" msgid="4564407557775397216">"Маб. перадача даных"</string>
<string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi выключаны"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth выключаны"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Рэжым \"Не турбаваць\" выключаны"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Рэжым \"Не турбаваць\" быў уключаны праграмай (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам ці праграмай."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спыніць трансляцыю"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Даступныя прылады для вываду аўдыя."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Гучнасць"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як адбываецца трансляцыя"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Трансляцыя"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Людзі паблізу, у якіх ёсць прылады з Bluetooth, змогуць праслухваць мультымедыйнае змесціва, якое вы трансліруеце"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера і мікрафон выключаны"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# апавяшчэнне}one{# апавяшчэнне}few{# апавяшчэнні}many{# апавяшчэнняў}other{# апавяшчэння}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Стварэнне нататак"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Перадача даных"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Спыніць трансляцыю праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Пры пераключэнні на праграму \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" ці змяненні вываду бягучая трансляцыя спыняецца"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Трансляцыя праграмы \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змяненне вываду"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невядома"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Адкрыць праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Усталявана праграма \"Камера\"."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Праграма наладжана."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Даступная хаця б адна прылада."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасаваць"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Пераключыць"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Каб атрымаць лепшае сэлфі, раскрыйце тэлефон"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Пераключыць на пярэднюю камеру для лепшага сэлфі?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Каб зрабіць шырэйшае фота з больш высокай раздзяляльнасцю, скарыстайце заднюю камеру."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Гэты экран будзе выключаны"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складная прылада ў раскладзеным выглядзе"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перавернутая складная прылада"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index c2860e9..2dd94d2 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Функцията за Wi‑Fi е изключена"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Функцията за Bluetooth е изключена"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Режимът „Не безпокойте“ е изключен"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режимът „Не безпокойте“ бе включен от автоматично правило (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Режимът „Не безпокойте“ бе включен от приложение (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Режимът „Не безпокойте“ бе включен от автоматично правило или от приложение."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спиране на предаването"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Налични устройства за аудиоизход."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Сила на звука"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работи предаването"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Предаване"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Хората в близост със съвместими устройства с Bluetooth могат да слушат мултимедията, която предавате"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонът са изключени"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известие}other{# известия}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Водене на бележки"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Излъчване"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се спре ли предаването на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако предавате <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените изхода, текущото ви предаване ще бъде прекратено"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Предаване на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промяна на изхода"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отваряне на <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Инсталирано е приложение за камера."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Приложението е настроено."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Налице е поне едно устройство."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отказ"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обръщане сега"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворете телефона за по-добро селфи"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Да се ползва ли предната камера за по-добро селфи?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Използвайте задната камера за по-широка снимка с по-висока разделителна способност."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Този екран ще се изключи"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Разгъване на сгъваемо устройство"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Обръщане на сгъваемо устройство"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 42fc489..864d7e7 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"ওয়াই ফাই বন্ধ আছে"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ বন্ধ আছে"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"বিরক্ত করবে না বিকল্পটি বন্ধ আছে"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"বিরক্ত করবে না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম <xliff:g id="ID_1">%s</xliff:g> এর দ্বারা চালু করা হয়েছে।"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"বিরক্ত করবে না বিকল্পটি একটি অ্যাপ <xliff:g id="ID_1">%s</xliff:g> এর দ্বারা চালু করা হয়েছে।"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"বিরক্ত করবে না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম বা অ্যাপের দ্বারা চালু করা হয়েছে।"</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করুন"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট পরিবর্তন করুন"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজানা"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> খুলুন"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ক্যামেরা অ্যাপ ইনস্টল করুন"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• অ্যাপ সেট-আপ করা হয়ে গেছে"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• অন্তত একটি ডিভাইস উপলভ্য"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল করুন"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এখনই উল্টান"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"আরও ভাল সেলফির জন্য ফোন আনফোল্ড করা"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"আরও ভাল সেলফির জন্য সামনের ক্যামেরায় পাল্টাতে চান?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"আরও ভাল রেজোলিউশন সহ আরও বেশি ওয়াইড ছবির জন্য ব্যাক-ক্যামেরা ব্যবহার করুন।"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ এই স্ক্রিন বন্ধ হয়ে যাবে"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ফোল্ড করা যায় এমন ডিভাইস খোলা হচ্ছে"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ফোল্ড করা যায় এমন ডিভাইস উল্টানো হচ্ছে"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 62f0c5f..87b6d3b 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"WiFi je isključen"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Način rada Ne ometaj je isključen"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Opciju Ne ometaju uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Način rada Ne ometaj uključila je aplikacija <xliff:g id="ID_1">%s</xliff:g>."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način rada Ne ometaj uključilo je automatsko pravilo ili aplikacija."</string>
@@ -986,14 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavještenje}one{# obavještenje}few{# obavještenja}other{# obavještenja}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Pisanje bilježaka"</string>
+ <string name="note_task_button_label" msgid="8718616095800343136">"Pisanje bilješki"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, trenutno emitiranje će se zaustaviti"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiraj aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promijeni izlaz"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvori aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Instalirajte aplikaciju kamere"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacija je postavljena"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostupan je najmanje jedan uređaj"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni sada"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Raširite telefon za bolji selfi"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Obrnuti na prednji ekran radi boljeg selfija?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite stražnju kameru za širu fotografiju veće rezolucije."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ekran će se isključiti"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Sklopivi uređaj se rasklapa"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Sklopivi uređaj se obrće"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 8f591bc..fcbd841 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"La Wi-Fi està desactivada"</string>
<string name="bt_is_off" msgid="7436344904889461591">"El Bluetooth està desactivat"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"El mode No molestis està desactivat"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Una regla automàtica (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Una aplicació (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Una regla automàtica o una aplicació han activat el mode No molestis."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Atura l\'emissió"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositius disponibles per a la sortida d\'àudio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volum"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Com funciona l\'emissió"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Emet"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les persones properes amb dispositius Bluetooth compatibles poden escoltar el contingut multimèdia que emets"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Càmera i micròfon desactivats"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificació}many{# notifications}other{# notificacions}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Presa de notes"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"S\'està emetent"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vols deixar d\'emetre <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emets <xliff:g id="SWITCHAPP">%1$s</xliff:g> o canvies la sortida, l\'emissió actual s\'aturarà"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emet <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Canvia la sortida"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconeguda"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Obre <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Tens una aplicació de càmera."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• L\'aplicació està configurada."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Almenys un dispositiu està disponible."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel·la"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Gira ara"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desplega el telèfon per fer una millor selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Girar a pantalla frontal per fer millors selfies?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilitza la càmera posterior per obtenir una foto més àmplia amb una resolució més alta."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Aquesta pantalla s\'apagarà"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositiu plegable que es desplega"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositiu plegable que gira"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index c417d44..3f6dd91 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je vypnuta"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je vypnuto"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Režim Nerušit je vypnut"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režim Nerušit byl zapnut automatickým pravidlem (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režim Nerušit byl zapnut aplikací (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režim Nerušit byl zapnut automatickým pravidlem nebo aplikací."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zastavit odesílání"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupná zařízení pro zvukový výstup."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Hlasitost"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak vysílání funguje"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Vysílání"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lidé ve vašem okolí s kompatibilními zařízeními Bluetooth mohou poslouchat média, která vysíláte"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparát a mikrofon jsou vypnuté"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# oznámení}few{# oznámení}many{# oznámení}other{# oznámení}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g> <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Poznámky"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysílání"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zastavit vysílání v aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Pokud budete vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g> nebo změníte výstup, aktuální vysílání se zastaví"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Změna výstupu"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznámé"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"H:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otevřít <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Je nainstalována aplikace pro fotoaparát"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikace je nastavena"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Je k dispozici alespoň jedno zařízení"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušit"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Otočit"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozložte telefon, selfie bude lepší"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Otočit na přední fotoaparát pro lepší selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Pomocí zadního fotoaparátu pořiďte širší fotku s vyšším rozlišením."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Tato obrazovka se vypne"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozkládání rozkládacího zařízení"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Otáčení rozkládacího zařízení"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index d4277a7..3596d0e 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi er slået fra"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth er slået fra"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Forstyr ikke er slået fra"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Tilstanden Forstyr ikke blev aktiveret af en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Tilstanden Forstyr ikke blev aktiveret af en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Tilstanden Forstyr ikke blev aktiveret af en automatisk regel eller en app."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Udsend <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skift output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukendt"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"tt.mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Åbn <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Installer en kameraapp"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Appen er konfigureret"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Mindst én enhed er tilgængelig"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuller"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vend nu"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Fold telefonen ud for at tage en bedre selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vil du bruge frontkameraet for at få bedre selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Brug bagsidekameraet for at få et bredere billede med højere opløsning."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ *Denne skærm slukkes"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldbar enhed foldes ud"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldbar enhed vendes om"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index d1c88fb..bcae5b4 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"WLAN ist deaktiviert"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ist deaktiviert"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"„Bitte nicht stören“ ist deaktiviert"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"„Bitte nicht stören“ wurde von einer automatischen Regel aktiviert (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"„Bitte nicht stören“ wurde von einer App aktiviert (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"„Bitte nicht stören“ wurde von einer automatischen Regel oder einer App aktiviert."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Streaming beenden"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Für die Audioausgabe verfügbare Geräte."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Lautstärke"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Funktionsweise von Nachrichten an alle"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Nachricht an alle"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personen, die in der Nähe sind und kompatible Bluetooth-Geräten haben, können sich die Medien anhören, die du per Nachricht an alle sendest"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera und Mikrofon ausgeschaltet"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# Benachrichtigung}other{# Benachrichtigungen}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Notizen machen"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Übertragung läuft"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> nicht mehr streamen?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Wenn du <xliff:g id="SWITCHAPP">%1$s</xliff:g> streamst oder die Ausgabe änderst, wird dein aktueller Stream beendet"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> streamen"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ausgabe ändern"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unbekannt"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> öffnen"</string>
@@ -1005,6 +1004,8 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera-App ist installiert"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Die App ist eingerichtet"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Mindestens ein Gerät ist verfügbar"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Abbrechen"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Jetzt umdrehen"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Für ein besseres Selfie Smartphone öffnen"</string>
@@ -1015,4 +1016,6 @@
<skip />
<!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
<skip />
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 84e18f0..54f162b 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Το Wi-Fi είναι ανενεργό"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Το Bluetooth είναι ανενεργό"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Η λειτουργία \"Μην ενοχλείτε\" είναι ανενεργή"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από μια εφαρμογή (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα ή μια εφαρμογή."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Αλλαγή εξόδου"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Άγνωστο"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"ΗΗΗ, ΜΜΜ η"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ώ:λλ"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:λλ"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Άνοιγμα <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Εγκαταστήσατε μια εφαρμογή κάμερας"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Η εφαρμογή έχει ρυθμιστεί"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Είναι διαθέσιμη τουλάχιστον μία συσκευή"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ακύρωση"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Αναστροφή τώρα"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ξεδιπλώστε το τηλέφωνο για καλύτερη selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Αναστροφή στην μπροστ. οθόνη για καλύτερη selfie;"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Χρησιμοποιήστε την πίσω κάμερα για να βγάλετε μια φωτογραφία με μεγαλύτερο εύρος και υψηλότερη ανάλυση."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Αυτή η οθόνη θα απενεργοποιηθεί"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Αναδιπλούμενη συσκευή που ξεδιπλώνει"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Αναδιπλούμενη συσκευή που διπλώνει"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 133bb64..224d6fc 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 4caf4e0..6238b83 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,14 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
+ <string name="keyguard_affordance_press_too_short" msgid="2687995216454987952">"Press and hold to activate"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
- <skip />
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+ <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 133bb64..224d6fc 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 133bb64..224d6fc 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index abb548b..7bb3fd3 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,14 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
+ <string name="keyguard_affordance_press_too_short" msgid="2687995216454987952">"Press and hold to activate"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930">""<b>"✱ This screen will turn off"</b>""</string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
- <skip />
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+ <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3527aaf..75fdd0d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desactivado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"No interrumpir desactivado"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Se activó el modo No interrumpir con una regla automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Se activó el modo No interrumpir con una app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Se activó el modo No interrumpir con una app o regla automática."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Detener transmisión"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponibles para salida de audio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volumen"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la transmisión"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Transmisión"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que transmites"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están apagados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}many{# notificaciones}other{# notificaciones}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Tomar notas"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitiendo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Quieres dejar de transmitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si transmites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu transmisión actual se detendrá"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia la salida"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Se instaló la app de Cámara."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Se configuró la app."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Hay al menos un dispositivo disponible."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Girar ahora"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para tomar una selfie mejor"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"¿Cambiar a pantalla frontal para mejores selfies?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa la cámara trasera para tomar una foto más amplia y con mejor resolución."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable siendo desplegado"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable siendo girado"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index dcc52b5..8ebe61d 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desactivado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"No molestar está desactivado"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Una regla automática (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Una aplicación (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Una aplicación o una regla automática han activado No molestar."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dejar de enviar contenido"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponibles para la salida de audio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volumen"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la emisión"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Emisión"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que emites"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están desactivados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}many{# notificaciones}other{# notificaciones}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Tomar notas"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiendo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Dejar de emitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu emisión actual se detendrá"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar salida"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Debes instalar una aplicación de cámara"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• La aplicación debe estar configurada"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Al menos un dispositivo debe estar disponible"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Girar ahora"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para hacer un selfie mejor"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"¿Usar pantalla frontal para hacer mejores selfies?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa la cámara trasera para hacer una foto más amplia y con mayor resolución."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable desplegándose"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable mostrado desde varios ángulos"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index afba616..5345e53 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"WiFi on välja lülitatud"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth on välja lülitatud"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Funktsioon Mitte segada on välja lülitatud"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automaatne reegel (<xliff:g id="ID_1">%s</xliff:g>) lülitas funktsiooni Mitte segada sisse."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Rakendus (<xliff:g id="ID_1">%s</xliff:g>) lülitas funktsiooni Mitte segada sisse."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automaatne reegel või rakendus lülitas funktsiooni Mitte segada sisse."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lõpeta ülekanne"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Saadaolevad seadmed heli esitamiseks."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Helitugevus"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kuidas ülekandmine toimib?"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Ülekanne"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Teie läheduses olevad inimesed, kellel on ühilduvad Bluetooth-seadmed, saavad kuulata teie ülekantavat meediat"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kaamera ja mikrofon on välja lülitatud"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# märguanne}other{# märguannet}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Märkmete tegemine"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Edastamine"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Kas peatada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> ülekandmine?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kui kannate rakendust <xliff:g id="SWITCHAPP">%1$s</xliff:g> üle või muudate väljundit, peatatakse teie praegune ülekanne"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Rakenduse <xliff:g id="SWITCHAPP">%1$s</xliff:g> ülekandmine"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Väljundi muutmine"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tundmatu"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ava <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Installige kaamerarakendus"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Rakendus on seadistatud"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Vähemalt üks seade on saadaval"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Tühista"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Pööra kohe ümber"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Voltige telefon parema selfi jaoks lahti"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Kas kasutada parema selfi jaoks esikaamerat?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Kasutage tagakülje kaamerat, et jäädvustada suurema eraldusvõimega laiem foto."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ See ekraan lülitatakse välja"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Volditava seadme lahtivoltimine"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Volditava seadme ümberpööramine"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 9ded73a..4ed4bc1 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wifi-konexioa desaktibatuta dago"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth bidezko konexioa desaktibatuta dago"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Ez molestatzeko modua desaktibatuta dago"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Ez molestatzeko modua aktibatu du arau automatiko batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Ez molestatzeko modua aktibatu du aplikazio batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Ez molestatzeko modua aktibatu du arau automatiko edo aplikazio batek."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Gelditu igorpena"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio-irteerarako gailu erabilgarriak."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Bolumena"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Nola funtzionatzen dute iragarpenek?"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Iragarri"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth bidezko gailu bateragarriak dituzten inguruko pertsonek iragartzen ari zaren multimedia-edukia entzun dezakete"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera eta mikrofonoa desaktibatuta daude"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# jakinarazpen}other{# jakinarazpen}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Oharrak idaztea"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Igortzen"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren audioa igortzeari utzi nahi diozu?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa igortzen baduzu, edo audio-irteera aldatzen baduzu, une hartako igorpena eten egingo da"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Igorri <xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Aldatu audio-irteera"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ezezaguna"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ireki <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera-aplikazio bat instalatu da."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikazioa konfiguratuta dago."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Gutxienez gailu bat erabilgarri dago."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Utzi"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Irauli"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ireki telefonoa autoargazki hobeak ateratzeko"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Telefonoa irauli nahi duzu autoargazki hobeak ateratzeko?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Erabili atzeko kamera kalitate handiagoko argazki zabalago bat ateratzeko."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Pantaila itzali egingo da"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Gailu tolesgarria zabaltzen"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Gailu tolesgarria biratzen"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index c93803e9..d304821 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi خاموش است"</string>
<string name="bt_is_off" msgid="7436344904889461591">"بلوتوث خاموش است"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"«مزاحم نشوید» خاموش است"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"قانون خودکاری (<xliff:g id="ID_1">%s</xliff:g>) «مزاحم نشوید» را روشن کرد."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"برنامهای (<xliff:g id="ID_1">%s</xliff:g>) «مزاحم نشوید» را روشن کرد."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"برنامه یا قانون خودکاری، «مزاحم نشوید» را روشن کرد."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"توقف پخش محتوا"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"دستگاههای دردسترس برای خروجی صدا."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"میزان صدا"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"همهفرتستی چطور کار میکند"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"همهفرستی"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"افرادی که در اطرافتان دستگاههای Bluetooth سازگار دارند میتوانند به رسانهای که همهفرستی میکنید گوش کنند"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"دوربین و میکروفون خاموش هستند"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اعلان}one{# اعلان}other{# اعلان}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>، <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"یادداشتبرداری"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"همهفرستی"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"همهفرستی <xliff:g id="APP_NAME">%1$s</xliff:g> متوقف شود؟"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر <xliff:g id="SWITCHAPP">%1$s</xliff:g> را همهفرستی کنید یا خروجی را تغییر دهید، همهفرستی کنونی متوقف خواهد شد"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"همهفرستی <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغییر خروجی"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامشخص"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"باز کردن <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• برنامه دوربین نصب شده باشد"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• برنامه راهاندازی شده باشد"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• حداقل یک دستگاه دردسترس باشد"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"لغو کردن"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"اکنون چرخانده شود"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"برای خویشگرفت بهتر، تلفن را باز کنید"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"برای خویشگرفت بهتر، از نمایشگر جلو استفاده شود؟"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"برای عکسی عریضتر با وضوح بالاتر، از دوربین عقب استفاده کنید."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ این صفحهنمایش خاموش خواهد شد"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"دستگاه تاشو درحال باز شدن"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"دستگاه تاشو درحال چرخش به اطراف"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index d3b2da3..6922fb0 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi on pois päältä"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ei ole käytössä"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Älä häiritse ‑tila on pois päältä"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automaattinen sääntö otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Sovellus otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automaattinen sääntö tai sovellus otti käyttöön Älä häiritse ‑tilan."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lopeta striimaus"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Käytettävissä olevat audiolaitteet"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Äänenvoimakkuus"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Miten lähetys toimii"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Lähetys"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lähistöllä olevat ihmiset, joilla on yhteensopiva Bluetooth-laite, voivat kuunnella lähettämääsi mediaa"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ja mikrofoni ovat pois päältä"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ilmoitus}other{# ilmoitusta}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Muistiinpanojen tekeminen"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Lähettää"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Lopetetaanko <xliff:g id="APP_NAME">%1$s</xliff:g>-sovelluksen lähettäminen?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jos lähetät <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta tai muutat ulostuloa, nykyinen lähetyksesi loppuu"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lähetä <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Muuta ulostuloa"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tuntematon"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"VKP, KKK p"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Avaa <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Asenna kamerasovellus"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Sovellus on otettu käyttöön"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ainakin yksi laite on käytettävissä"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Peru"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Käännä nyt"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Saat paremman selfien, kun levität puhelimen"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Käännä etunäytölle, jotta saat paremman selfien?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Voit ottaa laajemman kuvan korkeammalla resoluutiolla, kun käytät takakameraa."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Tämä näyttö sammutetaan"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Taitettava laite taitetaan"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Taitettava laite käännetään ympäri"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 0300e9c..36453f8 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Le Wi-Fi est désactivé"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Le Bluetooth est désactivé"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Le mode Ne pas déranger est désactivé"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode Ne pas déranger a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode Ne pas déranger a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode Ne pas déranger a été activé par une règle automatique ou une application."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Appareils disponibles pour la sortie audio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement de la diffusion"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Diffusion"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité disposant d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"L\'appareil photo et le micro sont désactivés"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}many{# de notifications}other{# notifications}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Prise de note"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion en cours…"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou changez la sortie, votre diffusion actuelle s\'arrêtera"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Changer la sortie"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• qu\'une application de caméra est installée;"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• que cette application est configurée;"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• qu\'au moins un appareil est utilisable;"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner maintenant"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Déplier le téléphone pour un meilleur égoportrait"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Retourner l\'écran pour un meilleur égoportrait?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilisez l\'appareil photo arrière pour une photo plus large avec une résolution supérieure."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Cet écran va s\'éteindre"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable en cours de dépliage"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable en train d\'être retourné"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index c1d58eb..61ac4c4 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -120,7 +120,7 @@
<string name="accessibility_menu" msgid="2701163794470513040">"Menu"</string>
<string name="accessibility_accessibility_button" msgid="4089042473497107709">"Accessibilité"</string>
<string name="accessibility_rotate_button" msgid="1238584767612362586">"Faire pivoter l\'écran"</string>
- <string name="accessibility_recent" msgid="901641734769533575">"Aperçu"</string>
+ <string name="accessibility_recent" msgid="901641734769533575">"Récents"</string>
<string name="accessibility_camera_button" msgid="2938898391716647247">"Appareil photo"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Téléphoner"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistance vocale"</string>
@@ -308,7 +308,7 @@
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Caméra accessible"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Micro et caméra accessibles"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Autre appareil"</string>
- <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activer/Désactiver l\'aperçu"</string>
+ <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activer/Désactiver l\'écran Récents"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Vous ne serez dérangé par aucun son ni aucune vibration, hormis ceux des alarmes, des rappels, des événements et des appels des contacts de votre choix. Le son continuera de fonctionner notamment pour la musique, les vidéos et les jeux."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"Vous ne serez dérangé par aucun son ni aucune vibration, hormis ceux des alarmes. Le son continuera de fonctionner notamment pour la musique, les vidéos et les jeux."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Personnaliser"</string>
@@ -447,14 +447,14 @@
<string name="sound_settings" msgid="8874581353127418308">"Son et vibreur"</string>
<string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Paramètres"</string>
<string name="screen_pinning_title" msgid="9058007390337841305">"L\'application est épinglée"</string>
- <string name="screen_pinning_description" msgid="8699395373875667743">"Elle restera visible jusqu\'à ce que vous la retiriez. Pour la retirer, appuyez de manière prolongée sur les boutons Retour et Aperçu."</string>
+ <string name="screen_pinning_description" msgid="8699395373875667743">"Elle restera visible jusqu\'à ce que vous la retiriez. Pour la retirer, appuyez de manière prolongée sur les boutons Retour et Récents."</string>
<string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Elle restera visible jusqu\'à ce que vous la retiriez. Pour la retirer, appuyez de manière prolongée sur les boutons Retour et Accueil."</string>
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Elle restera visible jusqu\'à ce que vous la retiriez. Pour la retirer, balayez-la vers le haut et gardez le doigt appuyé."</string>
- <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Elle restera visible jusqu\'à ce que vous la retiriez. Pour la retirer, appuyez de manière prolongée sur le bouton Aperçu."</string>
+ <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Elle restera visible jusqu\'à ce que vous la retiriez. Pour la retirer, appuyez de manière prolongée sur le bouton Récents."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Elle restera visible jusqu\'à ce que vous la retiriez. Pour la retirer, appuyez de manière prolongée sur le bouton Accueil."</string>
<string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Des données à caractère personnel, comme des contacts et le contenu d\'e-mails, peuvent être accessibles."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"D\'autres applications peuvent être ouvertes depuis une application épinglée."</string>
- <string name="screen_pinning_toast" msgid="8177286912533744328">"Pour que l\'appli ne soit plus épinglée, appuyez de manière prolongée sur les boutons Retour et Aperçu"</string>
+ <string name="screen_pinning_toast" msgid="8177286912533744328">"Pour que l\'appli ne soit plus épinglée, appuyez de manière prolongée sur les boutons Retour et Récents"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Pour que l\'appli ne soit plus épinglée, appuyez de manière prolongée sur les boutons Retour et Accueil"</string>
<string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Pour que l\'appli ne soit plus épinglée, balayez-la vers le haut et maintenez le doigt appuyé"</string>
<string name="screen_pinning_positive" msgid="3285785989665266984">"OK"</string>
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi désactivé"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth désactivé"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Mode \"Ne pas déranger\" désactivé"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode \"Ne pas déranger\" a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode \"Ne pas déranger\" a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode \"Ne pas déranger\" a été activé par une règle automatique ou une application."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Appareils disponibles pour la sortie audio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement des annonces"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Annonce"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité équipées d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Appareil photo et micro désactivés"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}many{# notifications}other{# notifications}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Prendre des notes"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion…"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou que vous modifiez le résultat, votre annonce actuelle s\'arrêtera"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Modifier le résultat"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM j"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Installer une appli d\'appareil photo"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• L\'appli est configurée"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Au moins un appareil est disponible"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner maintenant"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Déplier le téléphone pour un meilleur selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Passer à l\'écran frontal pour un meilleur selfie ?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilisez la caméra arrière pour prendre une photo plus large avec une résolution supérieure."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Cet écran sera désactivé"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable qui est déplié"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable qui est retourné"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index c1daa98..249a783 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"A wifi está desactivada"</string>
<string name="bt_is_off" msgid="7436344904889461591">"O Bluetooth está desactivado"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"O modo Non molestar está desactivado"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Unha norma automática (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Unha aplicación (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Unha aplicación ou norma automática activou o modo Non molestar."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Deter emisión"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos dispoñibles para a saída de audio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funcionan as difusións?"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Difusión"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As persoas que estean preto de ti e que dispoñan de dispositivos Bluetooth compatibles poden escoitar o contido multimedia que difundas"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A cámara e o micrófono están desactivados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificacións}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Toma de notas"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Difusión"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Queres deixar de emitir contido a través de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se emites contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou cambias de saída, a emisión en curso deterase"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar de saída"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Descoñecida"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Debes instalar a aplicación de cámara"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• A aplicación debe estar configurada"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ten que haber polo menos un dispositivo dispoñible"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Voltear agora"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desprega o teléfono para unha autofoto mellor"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Usar a cámara dianteira para unha autofoto mellor?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa a cámara traseira para sacar unha foto máis ampla e con maior resolución."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Desactivarase esta pantalla"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pregable abríndose"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pregable xirando"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 6e306c8..8959442 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"વાઇ-ફાઇ બંધ છે"</string>
<string name="bt_is_off" msgid="7436344904889461591">"બ્લૂટૂથ બંધ છે"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"ખલેલ પાડશો નહીં બંધ છે"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ખલેલ પાડશો નહીં એક ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ અથવા ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"આઉટપુટ બદલો"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"અજાણ"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ખોલો"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• કૅમેરા ઍપ ઇન્સ્ટૉલ કરી છે"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ઍપનું સેટઅપ કરેલું છે"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ઓછામાં ઓછું એક ડિવાઇસ ઉપલબ્ધ છે"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"રદ કરો"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"હમણાં જ ફ્લિપ કરો"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"બહેતર સેલ્ફી લેવા માટે ફોન ખોલો"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"બહેતર સેલ્ફી લેવા ફ્રન્ટ ડિસ્પ્લે પર ફ્લિપ કરીએ?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"વધુ ઉચ્ચ રિઝોલ્યુશનવાળો વિશાળ ફોટો લેવા માટે પાછલા કૅમેરાનો ઉપયોગ કરો."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ આ સ્ક્રીન બંધ થઈ જશે"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ અનફોલ્ડ કરવામાં આવી રહ્યું છે"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ ફ્લિપ કરવામાં આવી રહ્યું છે"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 5dba466..c39563e 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"वाई-फ़ाई बंद है"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ब्लूटूथ बंद है"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"परेशान न करें बंद है"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"एक ऑटोमैटिक नियम (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"एक ऐप्लिकेशन (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"एक ऑटोमैटिक नियम या ऐप्लिकेशन ने परेशान न करें को चालू कर दिया था."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्टिंग करना रोकें"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ऑडियो आउटपुट के लिए उपलब्ध डिवाइस."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"वॉल्यूम"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्ट करने की सुविधा कैसे काम करती है"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करें"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"आपके आस-पास मौजूद लोग, ब्रॉडकास्ट किए जा रहे मीडिया को सुन सकते हैं. हालांकि, इसके लिए उनके पास ऐसे ब्लूटूथ डिवाइस होने चाहिए जिन पर मीडिया चलाया जा सके"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कैमरा और माइक बंद हैं"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}one{# सूचना}other{# सूचनाएं}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"नोट बनाएं"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट ऐप्लिकेशन"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर ब्रॉडकास्ट करना रोकें?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट शुरू करने पर या आउटपुट बदलने पर, आपका मौजूदा ब्रॉडकास्ट बंद हो जाएगा"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट करें"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट बदलें"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"कोई जानकारी नहीं"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> खोलें"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• कैमरा ऐप्लिकेशन इंस्टॉल किया गया है"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ऐप्लिकेशन को सेट अप किया गया है"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• कम से कम एक डिवाइस उपलब्ध है"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करें"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"कैमरा अभी स्विच करें"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"बेहतर सेल्फ़ी के लिए फ़ोन को अनफ़ोल्ड करें"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"बेहतर सेल्फ़ी के लिए फ़्रंट डिसप्ले पर स्विच करें?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"वाइड ऐंगल में हाई रिज़ॉल्यूशन वाली फ़ोटो लेने के लिए, पीछे का कैमरा इस्तेमाल करें."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ यह स्क्रीन बंद हो जाएगी"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फ़ोल्ड किया जा सकने वाला डिवाइस अनफ़ोल्ड किया जा रहा है"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फ़ोल्ड किया जा सकने वाला डिवाइस पलटा जा रहा है"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 13f43be..920869b 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je isključen"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Način Ne uznemiravaj isključen"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Način Ne uznemiravaj uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Način Ne uznemiravaj uključila je aplikacija (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način Ne uznemiravaj uključilo je automatsko pravilo ili aplikacija."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiranje aplikacije <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promjena izlaza"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE., d. MMM."</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvorite <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Instalirajte aplikaciju fotoaparata"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacija je postavljena"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostupan je najmanje jedan uređaj"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Odustani"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Okreni odmah"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon da biste snimili bolji selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Prebaciti na prednji zaslon za bolji selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Upotrijebite stražnji fotoaparat za širu fotografiju s višom razlučivošću."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ovaj će se zaslon isključiti"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rasklopljen sklopivi uređaj"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Okretanje sklopivog uređaja sa svih strana"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 7c816c7..77d5799 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"A Wi-Fi ki van kapcsolva"</string>
<string name="bt_is_off" msgid="7436344904889461591">"A Bluetooth ki van kapcsolva"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"A „Ne zavarjanak” mód ki van kapcsolva"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Az egyik automatikus szabály (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Az egyik alkalmazás (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Az egyik alkalmazás vagy automatikus szabály bekapcsolta a „Ne zavarjanak” módot."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Átküldés leállítása"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Rendelkezésre álló eszközök a hangkimenethez."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Hangerő"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"A közvetítés működése"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Közvetítés"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"A közelben tartózkodó, kompatibilis Bluetooth-eszközzel rendelkező személyek meghallgathatják az Ön közvetített médiatartalmait"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A kamera és a mikrofon ki vannak kapcsolva"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# értesítés}other{# értesítés}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Jegyzetelés"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sugárzás"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Leállítja a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> közvetítését?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"A(z) <xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése vagy a kimenet módosítása esetén a jelenlegi közvetítés leáll"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Kimenet módosítása"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ismeretlen"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, HHH n"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ó:pp"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"óó:pp"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> megnyitása"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kameraalkalmazás telepítése"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Az alkalmazás be van állítva"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Legalább egy eszköz rendelkezésre áll"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Mégse"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Átfordítás most"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Hajtsa ki a telefont jobb szelfi készítéséhez"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Átfordítja az előlapi kijelzőre a jobb szelfiért?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Használja az előlapi kamerát, hogy nagyobb felbontású, szélesebb fotót készíthessen"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ A képernyő kikapcsol"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Összehajtható eszköz kihajtása"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Összehajtható eszköz körbeforgatása"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index ea60237..6c770d3 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi-ն անջատված է"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth-ն անջատված է"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Չանհանգստացնելու ռեժիմն անջատված է"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Չանհանգստացնել գործառույթը միացված է ավտոմատ կանոնի կողմից (<xliff:g id="ID_1">%s</xliff:g>):"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Չանհանգստացնել գործառույթը միացված է հավելվածի կողմից (<xliff:g id="ID_1">%s</xliff:g>):"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Չանհանգստացնել գործառույթը միացված է ավտոմատ կանոնի կամ հավելվածի կողմից:"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Կանգնեցնել հեռարձակումը"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Հասանելի սարքեր ձայնի արտածման համար։"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Ձայնի ուժգնություն"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ինչպես է աշխատում հեռարձակումը"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Հեռարձակում"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ձեր մոտակայքում գտնվող՝ համատեղելի Bluetooth սարքերով մարդիկ կարող են լսել մեդիա ֆայլերը, որոնք դուք հեռարձակում եք։"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Տեսախցիկը և խոսափողն անջատված են"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ծանուցում}one{# ծանուցում}other{# ծանուցում}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Նշումների ստեղծում"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Հեռարձակում"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Կանգնեցնել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի հեռարձակումը"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Եթե հեռարձակեք <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը կամ փոխեք աուդիո ելքը, ձեր ընթացիկ հեռարձակումը կկանգնեցվի։"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Հեռարձակել <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Փոխել աուդիո ելքը"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Անհայտ"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Բացել <xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• «Տեսախցիկ» հավելվածը տեղադրված է"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Հավելվածը կարգավորված է"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Հասանելի է առնվազն մեկ սարք"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Չեղարկել"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Շրջել հիմա"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Բացեք հեռախոսի փեղկը՝ ավելի լավ սելֆի անելու համար"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Հեռախոսը էկրանով դեպի ձե՞զ շրջեցիք"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Օգտագործեք հետևի տեսախցիկը՝ ավելի բարձր լուծաչափով և ավելի լայն լուսանկար ստանալու համար։"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Այս էկրանը կանջատվի"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ծալովի սարք՝ բացված վիճակում"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Ծալովի սարք՝ շրջված վիճակում"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3cdb26e..3bbcc82 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi nonaktif"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth nonaktif"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Fitur Jangan Ganggu nonaktif"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Mode Jangan Ganggu diaktifkan oleh aturan otomatis (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Mode Jangan Ganggu diaktifkan oleh aplikasi (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Mode Jangan Ganggu diaktifkan oleh aturan otomatis atau aplikasi."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hentikan transmisi"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Perangkat yang tersedia untuk output audio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara kerja siaran"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Siaran"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang di dekat Anda dengan perangkat Bluetooth yang kompatibel dapat mendengarkan media yang sedang Anda siarkan"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon nonaktif"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikasi}other{# notifikasi}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Pembuatan catatan"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika Anda menyiarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau mengubah output, siaran saat ini akan dihentikan"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ubah output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Menginstal aplikasi kamera"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikasi disiapkan"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Tersedia minimal satu perangkat"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Balik sekarang"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Bentangkan ponsel untuk selfie yang lebih baik"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Gunakan layar depan untuk selfie yang lebih baik?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gunakan kamera belakang untuk foto dengan resolusi lebih tinggi dan lebih lebar."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Layar ini akan dinonaktifkan"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Perangkat foldable sedang dibentangkan"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Perangkat foldable sedang dibalik"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 7c715382..a42f42e 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Slökkt á Wi-Fi"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Slökkt á Bluetooth"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Slökkt á „Ónáðið ekki“"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Sjálfvirk regla kveikti á „Ónáðið ekki“ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Forrit kveikti á „Ónáðið ekki“ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Sjálfvirk regla eða forrit kveikti á „Ónáðið ekki“"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stöðva útsendingu"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Tæki í boði fyrir hljóðúttak."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Hljóðstyrkur"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Svona virkar útsending"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Útsending"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Fólk nálægt þér með samhæf Bluetooth-tæki getur hlustað á efnið sem þú sendir út"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Slökkt á myndavél og hljóðnema"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# tilkynning}one{# tilkynning}other{# tilkynningar}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Glósugerð"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Útsending í gangi"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hætta að senda út <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ef þú sendir út <xliff:g id="SWITCHAPP">%1$s</xliff:g> eða skiptir um úttak lýkur yfirstandandi útsendingu"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Senda út <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skipta um úttak"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Óþekkt"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"k:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Opna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Setja upp myndavélarforrit"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Forritið er uppsett"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Að minnsta kosti eitt tæki er tiltækt"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Hætta við"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Snúa núna"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Opnaðu símann til að taka betri sjálfsmynd"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Snúa á framskjá til að ná betri sjálfsmynd?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Notaðu aftari myndavélina til að ná víðara sjónarhorni með meiri upplausn."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Slökkt verður á þessum skjá"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Samanbrjótanlegt tæki opnað"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Samanbrjótanlegu tæki snúið við"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index f6c8354..8e0efa8 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi disattivato"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth non attivo"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Funzione Non disturbare disattivata"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"La funzione Non disturbare è stata attivata da una regola automatica (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"La funzione Non disturbare è stata attivata da un\'app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"La funzione Non disturbare è stata attivata da una regola automatica o da un\'app."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Interrompi trasmissione"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivi disponibili per l\'uscita audio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Come funziona la trasmissione"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Annuncio"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Le persone vicine a te che hanno dispositivi Bluetooth compatibili possono ascoltare i contenuti multimediali che stai trasmettendo"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotocamera e microfono non attivi"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifica}many{# notifiche}other{# notifiche}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Aggiunta di note"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Trasmissione in corso…"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vuoi interrompere la trasmissione dell\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambi l\'uscita, la trasmissione attuale viene interrotta"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia uscita"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM g"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Apri <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Sia installata un\'app fotocamera"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• L\'app sia configurata"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ci sia almeno un dispositivo disponibile"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annulla"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Gira ora"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Apri il telefono per un selfie migliore"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Girare su display frontale per un selfie migliore?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilizza la fotocamera posteriore per una foto più ampia con maggiore risoluzione."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Questo schermo verrà disattivato"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pieghevole che viene aperto"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pieghevole che viene capovolto"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8e12a0b..5f74a57 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi כבוי"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth כבוי"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"מצב \'נא לא להפריע\' כבוי"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"מצב \'נא לא להפריע\' הופעל על ידי כלל אוטומטי (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה או על ידי כלל אוטומטי."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"עצירת ההעברה (casting)"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"מכשירים זמינים לפלט אודיו."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"עוצמת הקול"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"הסבר על שידורים"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"שידור"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"אנשים בקרבת מקום עם מכשירי Bluetooth תואמים יכולים להאזין למדיה שמשודרת על ידך"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"המצלמה והמיקרופון כבויים"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{התראה אחת}one{# התראות}two{# התראות}other{# התראות}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"כתיבת הערות"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"שידור"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"האם להפסיק לשדר את התוכן מאפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"אם משדרים את התוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g> או משנים את הפלט, השידור הנוכחי יפסיק לפעול"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"שידור תוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"שינוי הפלט"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"לא ידוע"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"יום EEE, d בMMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"פתיחת <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,6 +1004,8 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• התקנה של אפליקציית מצלמה"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• האפליקציה מוגדרת"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• יש לפחות מכשיר אחד זמין"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ביטול"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"הפכת את המכשיר"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"כדי לצלם תמונת סלפי טובה יותר, פותחים את הטלפון"</string>
@@ -1015,4 +1016,6 @@
<skip />
<!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
<skip />
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 0cacdbd..485161f 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi は OFF です"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth は OFF です"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"サイレント モードは OFF です"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"サイレント モードが自動ルール(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"サイレント モードがアプリ(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"サイレント モードが自動ルールまたはアプリによって ON になりました。"</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャスト"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"出力を変更"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> を開く"</string>
@@ -1003,14 +1004,14 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• カメラアプリをインストールする"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• アプリが設定されている"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 利用できるデバイスが 1 台以上ある"</string>
+ <string name="keyguard_affordance_press_too_short" msgid="2687995216454987952">"有効にするには長押ししてください"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"キャンセル"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"切り替えましょう"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"高画質で撮るにはスマートフォンを開いてください"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"前面ディスプレイに切り替えて綺麗に撮りましょう"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"高解像度で広い範囲を撮影するには、背面カメラを使用してください。"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱この画面は OFF になります"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
- <skip />
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"折りたたみ式デバイスが広げられている"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"折りたたみ式デバイスがひっくり返されている"</string>
+ <string name="stylus_battery_low" msgid="7134370101603167096">"タッチペンのバッテリー残量が少なくなっています"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 038937d..f9e9b13 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi გამორთულია"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth გამორთულია"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"„არ შემაწუხოთ“ რეჟიმი გამორთულია"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"„არ შემაწუხოთ“ ჩაირთო ავტომატური წესის მიხედვით (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"„არ შემაწუხოთ“ ჩაირთო აპის მიერ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"„არ შემაწუხოთ“ ჩაირთო ავტომატური წესის მიხედვით ან აპის მიერ."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაცია"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"აუდიოს გამოსასვლელის შეცვლა"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"უცნობი"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"დდდ, თთთ თ"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"სთ:წთ"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"სთ:წთ"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> აპის გახსნა"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• დააინსტალირეთ კამერის აპი"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• აპი დაყენებულია"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ხელმისაწვდომია მინიმუმ ერთი მოწყობილობა"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"გაუქმება"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"გადაატრიალეთ ახლა"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"გაშალეთ ტელეფონი უკეთესი სელფისთვის"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"გადააბრუნეთ წინა ეკრანზე უკეთესი სელფის მისაღებად?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"გამოიყენეთ უკანა კამერა უფრო ფართო ფოტოს გადასაღებად მაღალი გარჩევადობით."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ეს ეკრანი გამოირთვება"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"დასაკეცი მოწყობილობა იხსნება"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"დასაკეცი მოწყობილობა ტრიალებს"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 91c0b35..8619a95 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi өшірулі"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth өшірулі"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Мазаламау режимі өшірулі"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Мазаламау режимі (<xliff:g id="ID_1">%s</xliff:g>) автоматты ережесі арқылы қосылды."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Мазаламау режимі (<xliff:g id="ID_1">%s</xliff:g>) қолданбасы арқылы қосылды."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Мазаламау режимі автоматты ереже немесе қолданба арқылы қосылды."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Трансляцияны тоқтату"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Аудио шығыс үшін қолжетімді құрылғылар бар."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Дыбыс деңгейі"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Тарату қалай жүзеге асады"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Тарату"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Үйлесімді Bluetooth құрылғылары бар маңайдағы адамдар сіз таратып жатқан медиамазмұнды тыңдай алады."</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера мен микрофон өшірулі"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# хабарландыру}other{# хабарландыру}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Ескертпе жазу"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Таратуда"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын таратуды тоқтатасыз ба?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын таратсаңыз немесе аудио шығысын өзгертсеңіз, қазіргі тарату сеансы тоқтайды."</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын тарату"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудио шығысын өзгерту"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгісіз"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ашу"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Камера қолданбасын орнатыңыз"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Қолданба реттелген"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Кемінде бір құрылғы қолжетімді"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Бас тарту"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Айналдыру"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Жақсырақ селфи түсіру үшін телефонды жазыңыз"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Жақсырақ селфи үшін алдыңғы экранға ауысасыз ба?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Ажыратымдылығы жоғары кеңірек фотосурет түсіру үшін артқы камераны пайдаланыңыз."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Бұл экран өшіріледі."</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Бүктемелі құрылғы ашылып жатыр."</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Бүктемелі құрылғы аударылып жатыр."</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 51e5b53..6914431 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi បានបិទ"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ប៊្លូធូសបានបិទ"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"មុខងារកុំរំខានបានបិទ"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"មុខងារកុំរំខានត្រូវបានបើកដោយច្បាប់ស្វ័យប្រវត្តិ (<xliff:g id="ID_1">%s</xliff:g>)។"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"មុខងារកុំរំខានត្រូវបានបើកដោយកម្មវិធី (<xliff:g id="ID_1">%s</xliff:g>)។"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"មុខងារកុំរំខានត្រូវបានបើកដោយច្បាប់ស្វ័យប្រវត្តិ ឬកម្មវិធី។"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"បញ្ឈប់ការភ្ជាប់"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ឧបករណ៍ដែលអាចប្រើបានសម្រាប់ឧបករណ៍បញ្ចេញសំឡេង។"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"កម្រិតសំឡេង"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"របៀបដែលការផ្សាយដំណើរការ"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ការផ្សាយ"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"មនុស្សនៅជិតអ្នកដែលមានឧបករណ៍ប៊្លូធូសត្រូវគ្នាអាចស្តាប់មេឌៀដែលអ្នកកំពុងផ្សាយបាន"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"កាមេរ៉ា និងមីក្រូហ្វូនត្រូវបានបិទ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{ការជូនដំណឹង #}other{ការជូនដំណឹង #}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"ការកត់ត្រា"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ការផ្សាយ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"បញ្ឈប់ការផ្សាយ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ប្រសិនបើអ្នកផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ឬប្ដូរឧបករណ៍បញ្ចេញសំឡេង ការផ្សាយបច្ចុប្បន្នរបស់អ្នកនឹងបញ្ឈប់"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ការផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ប្ដូរឧបករណ៍បញ្ចេញសំឡេង"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"មិនស្គាល់"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"បើក <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ដំឡើងកម្មវិធីកាមេរ៉ា"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• កម្មវិធីត្រូវបានរៀបចំ"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ឧបករណ៍យ៉ាងតិចមួយអាចប្រើបាន"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"បោះបង់"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ត្រឡប់ឥឡូវនេះ"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"លាតទូរសព្ទ ដើម្បីសែលហ្វីកាន់តែប្រសើរ"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ត្រឡប់ទៅផ្ទាំងអេក្រង់ខាងមុខ ដើម្បីថតសែលហ្វីកាន់តែបានល្អឬ?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ប្រើកាមេរ៉ាខាងក្រោយ ដើម្បីទទួលបានរូបថតកាន់តែធំជាមួយនឹងកម្រិតគុណភាពកាន់តែខ្ពស់។"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ អេក្រង់នេះនឹងបិទ"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ឧបករណ៍អាចបត់បានកំពុងត្រូវបានលា"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ឧបករណ៍អាចបត់បានកំពុងត្រូវបានលា"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 5baf68f..2691a70 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"ವೈ-ಫೈ ಆಫ್ ಆಗಿದೆ"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ಬ್ಲೂಟೂತ್ ಆಫ್ ಆಗಿದೆ"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆಫ್ ಆಗಿದೆ"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"(<xliff:g id="ID_1">%s</xliff:g>) ಸ್ವಯಂಚಾಲಿತ ನಿಯಮದ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"(<xliff:g id="ID_1">%s</xliff:g>) ಅಪ್ಲಿಕೇಶನ್ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ಸ್ವಯಂಚಾಲಿತ ನಿಯಮ ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿ"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ಔಟ್ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ಅಪರಿಚಿತ"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ಕ್ಯಾಮರಾ ಆ್ಯಪ್ ಒಂದನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ಆ್ಯಪ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ಕನಿಷ್ಠ ಒಂದು ಸಾಧನ ಲಭ್ಯವಿದೆ"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ರದ್ದುಗೊಳಿಸಿ"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ಈಗ ಫ್ಲಿಪ್ ಮಾಡಿ"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ಉತ್ತಮ ಸೆಲ್ಫೀಗಾಗಿ ಫೋನ್ ಅನ್ನು ಅನ್ಫೋಲ್ಡ್ ಮಾಡಿ"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ಉತ್ತಮ ಸೆಲ್ಫೀಗಾಗಿ ಮುಂಭಾಗದ ಕ್ಯಾಮರಾಗೆ ಫ್ಲಿಪ್ ಮಾಡಬೇಕೆ?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ಹೆಚ್ಚಿನ ರೆಸಲ್ಯೂಷನ್ ಹೊಂದಿರುವ ವಿಶಾಲವಾದ ಫೋಟೋಗಾಗಿ ಹಿಂಭಾಗದ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸಿ."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ಈ ಸ್ಕ್ರೀನ್ ಆಫ್ ಆಗುತ್ತದೆ"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಅನ್ಫೋಲ್ಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಸುತ್ತಲೂ ತಿರುಗಿಸಲಾಗುತ್ತಿದೆ"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 9b8e46a..f3f0426 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi가 사용 중지됨"</string>
<string name="bt_is_off" msgid="7436344904889461591">"블루투스가 사용 중지됨"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"방해 금지 모드가 사용 중지됨"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"방해 금지 모드가 자동 규칙(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"방해 금지 모드가 앱(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"방해 금지 모드가 자동 규칙 또는 앱에 의해 사용 설정되었습니다."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"전송 중지"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"오디오 출력에 사용 가능한 기기입니다."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"볼륨"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"브로드캐스팅 작동 원리"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"브로드캐스트"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"호환되는 블루투스 기기를 가진 근처의 사용자가 내가 브로드캐스트 중인 미디어를 수신 대기할 수 있습니다."</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"카메라 및 마이크가 사용 중지되었습니다."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{알림 #개}other{알림 #개}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"메모"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"방송 중"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> 방송을 중지하시겠습니까?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 앱을 방송하거나 출력을 변경하면 기존 방송이 중단됩니다"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 방송"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"출력 변경"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"알 수 없음"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d일 EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> 열기"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• 카메라 앱이 설치되어 있습니다."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• 앱이 설정되어 있습니다."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 1대 이상의 기기를 사용할 수 있습니다."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"취소"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"지금 뒤집기"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"휴대전화를 열어서 더 나은 셀카를 찍어보세요"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"전면 디스플레이가 보이도록 뒤집어서 더 나은 셀카를 찍어보세요"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"후면 카메라를 통해 넓은 각도로 해상도가 높은 사진을 찍어보세요."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 이 화면이 꺼집니다."</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"폴더블 기기를 펼치는 모습"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"폴더블 기기를 뒤집는 모습"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index bb55c62..6f64f45 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi өчүк"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth өчүк"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"\"Тынчымды алба\" режими өчүк"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автоматтык эреже \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Колдонмо \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автоматтык эреже же колдонмо \"Тынчымды алба\" режимин күйгүздү."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Тышкы экранга чыгарууну токтотуу"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Аудио чыгаруу үчүн жеткиликтүү түзмөктөр."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Үндүн катуулугу"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Кабарлоо кантип иштейт"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Кабарлоо"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Шайкеш Bluetooth түзмөктөрү болгон жакын жердеги кишилер кабарлап жаткан медиаңызды уга алышат"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера жана микрофон өчүк"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# билдирме}other{# билдирме}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Эскертме жазуу"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Кеңири таратуу"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда кабарлоо токтотулсунбу?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Эгер <xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарласаңыз же аудионун чыгуусун өзгөртсөңүз, учурдагы кабарлоо токтотулат"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарлоо"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудионун чыгуусун өзгөртүү"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгисиз"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ачуу"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Камера колдонмосун орнотуу"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Колдонмо туураланды"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Кеминде бир түзмөк жеткиликтүү"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Токтотуу"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Азыр которуу"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Жакшы селфи тартуу үчүн негизги камерага которуңуз"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Жакшы селфи тартуу үчүн маңдайкы экранга которосузбу?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Кең жана жогорку дааналыктагы сүрөттү тартуу үчүн негизги камераны колдонуңуз."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Бул экран өчөт"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ачылып турган бүктөлмө түзмөк"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Оодарылып жаткан бүктөлмө түзмөк"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index da353e6..8573f69 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ປິດຢູ່"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ປິດຢູ່"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"ຫ້າມລົບກວນ ປິດຢູ່"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ມີແອັບເປີດໃຊ້ໂໝດຫ້າມລົບກວນ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ ຫຼື ແອັບໃດໜຶ່ງ."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ຢຸດການສົ່ງສັນຍານ"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ອຸປະກອນທີ່ສາມາດໃຊ້ໄດ້ສຳລັບເອົ້າພຸດສຽງ."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ລະດັບສຽງ"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ການອອກອາກາດເຮັດວຽກແນວໃດ"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ອອກອາກາດ"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ຄົນທີ່ຢູ່ໃກ້ທ່ານທີ່ມີອຸປະກອນ Bluetooth ທີ່ເຂົ້າກັນໄດ້ຈະສາມາດຟັງມີເດຍທີ່ທ່ານກຳລັງອອກອາກາດຢູ່ໄດ້"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ປິດກ້ອງຖ່າຍຮູບ ແລະ ໄມແລ້ວ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ການແຈ້ງເຕືອນ}other{# ການແຈ້ງເຕືອນ}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"ການຈົດບັນທຶກ"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ກຳລັງອອກອາກາດ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ຢຸດການອອກອາກາດ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ຫາກທ່ານອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ຫຼື ປ່ຽນເອົ້າພຸດ, ການອອກອາກາດປັດຈຸບັນຂອງທ່ານຈະຢຸດ"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ປ່ຽນເອົ້າພຸດ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ບໍ່ຮູ້ຈັກ"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ຊມ:ນທ"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ຊມ:ນທ"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"ເປີດ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ຕິດຕັ້ງແອັບກ້ອງຖ່າຍຮູບ"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ແອັບໄດ້ຮັບການຕັ້ງຄ່າແລ້ວ"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ມີຢ່າງໜ້ອຍ 1 ອຸປະກອນພ້ອມໃຫ້ນຳໃຊ້"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ຍົກເລີກ"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ປີ້ນດຽວນີ້"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ກາງໂທລະສັບອອກເພື່ອການຖ່າຍເຊວຟີທີ່ດີຂຶ້ນ"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ປີ້ນເປັນຈໍສະແດງຜົນດ້ານໜ້າເພື່ອການຖ່າຍເຊວຟີທີ່ດີຂຶ້ນບໍ?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ໃຊ້ກ້ອງຫຼັງເພື່ອການຖ່າຍຮູບທີ່ກວ້າງຂຶ້ນດ້ວຍຄວາມລະອຽດສູງຂຶ້ນ."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ໜ້າຈໍນີ້ຈະປິດ"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ອຸປະກອນທີ່ພັບໄດ້ກຳລັງກາງອອກ"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ອຸປະກອນທີ່ພັກໄດ້ກຳລັງປີ້ນໄປມາ"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 96c4371..3af4eb0 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"„Wi-Fi“ išjungtas"</string>
<string name="bt_is_off" msgid="7436344904889461591">"„Bluetooth“ išjungtas"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Netrukdymo režimas išjungtas"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Netrukdymo režimą įjungė automatinė taisyklė (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Netrukdymo režimą įjungė programa (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Netrukdymo režimą įjungė automatinė taisyklė arba programa."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sustabdyti perdavimą"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Pasiekiami garso išvesties įrenginiai."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Garsumas"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kaip veikia transliacija"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Transliacija"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Netoliese esantys žmonės, turintys suderinamus „Bluetooth“ įrenginius, gali klausyti jūsų transliuojamos medijos"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Vaizdo kamera ir mikrofonas išjungti"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pranešimas}one{# pranešimas}few{# pranešimai}many{# pranešimo}other{# pranešimų}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Užrašų kūrimas"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transliavimas"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Sustabdyti „<xliff:g id="APP_NAME">%1$s</xliff:g>“ transliaciją?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jei transliuosite „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“ arba pakeisite išvestį, dabartinė transliacija bus sustabdyta"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transliuoti „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Keisti išvestį"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nežinoma"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Atidaryti „<xliff:g id="APPNAME">%1$s</xliff:g>“"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Įdiekite Fotoaparato programą"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Programa nustatyta"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pasiekiamas bent vienas įrenginys"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atšaukti"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Apversti dabar"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Užfiksuokite geresnę asmenukę atlenkę telefoną"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Užfiksuoti geresnę asmenukę įjungus priekinį rodinį?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Naudokite galinį fotoaparatą, kad nuotrauka būtų platesnė ir didesnės skyros."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Šis ekranas išsijungs"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Lankstomasis įrenginys išlankstomas"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Lankstomasis įrenginys apverčiamas"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 1c22380..cec24a4 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ir izslēgts"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ir izslēgts"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Režīms “Netraucēt” ir izslēgts"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režīmu “Netraucēt” ieslēdza automātiska kārtula (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režīmu “Netraucēt” ieslēdza lietotne (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režīmu “Netraucēt” ieslēdza automātiska kārtula vai lietotne."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Apturēt apraidi"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio izvadei pieejamās ierīces."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Skaļums"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kā darbojas apraide"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Apraide"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Tuvumā esošās personas ar saderīgām Bluetooth ierīcēm var klausīties jūsu apraidīto multivides saturu."</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera un mikrofons ir izslēgti"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# paziņojums}zero{# paziņojumu}one{# paziņojums}other{# paziņojumi}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Piezīmju pierakstīšana"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Notiek apraidīšana"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vai apturēt lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> apraidīšanu?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ja sāksiet lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraidīšanu vai mainīsiet izvadi, pašreizējā apraide tiks apturēta"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraide"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Izvades maiņa"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nezināms"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Atvērt lietotni <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Ir instalēta kameras lietotne."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Lietotne ir iestatīta."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ir pieejama vismaz viena ierīce."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atcelt"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Apvērst tūlīt"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Labākas pašbildes uzņemšana, atlokot tālruni"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vai apvērst uz priekšējo kameru labākai pašbildei?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Lai uzņemtu platāku fotoattēlu ar augstāku izšķirtspēju, izmantojiet aizmugurējo kameru."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Šis ekrāns tiks izslēgts."</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Salokāma ierīce tiek atlocīta"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Salokāma ierīce tiek apgriezta"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 603151f..fff051b 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi е исклучено"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth е исклучен"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"„Не вознемирувај“ е исклучено"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Едно автоматско правило (<xliff:g id="ID_1">%s</xliff:g>) ја вклучи „Не вознемирувај“."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Една апликација (<xliff:g id="ID_1">%s</xliff:g>) ја вклучи „Не вознемирувај“."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Едно автоматско правило или апликација ја вклучи „Не вознемирувај“."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитување на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Променете излез"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворете ја <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• инсталирана е апликација за камера"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• апликацијата е поставена"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• достапен е најмалку еден уред"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Префрли сега"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворете го телефонот за подобро селфи"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Да се префрли на предниот екран за подобро селфи?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Користете ја задната камера за поширока фотографија со повисока резолуција."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Екранов ќе се исклучи"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Преклопувачки уред се отклопува"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Преклопувачки уред се врти"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 5df7305..6f52102 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"വൈഫൈ ഓഫാണ്"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ഓഫാണ്"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"\'ശല്യപ്പെടുത്തരുത്\' ഓഫാണ്"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"സ്വയമേവയുള്ള ഒരു നയം (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ഒരു ആപ്പ് (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"സ്വയമേവയുള്ള ഒരു നയമോ ആപ്പോ \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"കാസ്റ്റ് ചെയ്യുന്നത് നിർത്തുക"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ഓഡിയോ ഔട്ട്പുട്ടിന് ലഭ്യമായ ഉപകരണങ്ങൾ."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"വോളിയം"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ബ്രോഡ്കാസ്റ്റ് എങ്ങനെയാണ് പ്രവർത്തിക്കുന്നത്"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ബ്രോഡ്കാസ്റ്റ്"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"അനുയോജ്യമായ Bluetooth ഉപകരണങ്ങളോടെ സമീപമുള്ള ആളുകൾക്ക് നിങ്ങൾ ബ്രോഡ്കാസ്റ്റ് ചെയ്യുന്ന മീഡിയ കേൾക്കാനാകും"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ക്യാമറയും മൈക്കും ഓഫാണ്"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# അറിയിപ്പ്}other{# അറിയിപ്പുകൾ}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"കുറിപ്പ് രേഖപ്പെടുത്തൽ"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"പ്രക്ഷേപണം ചെയ്യുന്നു"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബ്രോഡ്കാസ്റ്റ് ചെയ്യുന്നത് അവസാനിപ്പിക്കണോ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"നിങ്ങൾ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്കാസ്റ്റ് ചെയ്യുകയോ ഔട്ട്പുട്ട് മാറ്റുകയോ ചെയ്താൽ നിങ്ങളുടെ നിലവിലുള്ള ബ്രോഡ്കാസ്റ്റ് അവസാനിക്കും"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്കാസ്റ്റ് ചെയ്യുക"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ഔട്ട്പുട്ട് മാറ്റുക"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"അജ്ഞാതം"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> തുറക്കുക"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ഒരു ക്യാമറാ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തിട്ടുണ്ട്"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ആപ്പ് സജ്ജീകരിച്ചിട്ടുണ്ട്"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ഒരു ഉപകരണമെങ്കിലും ലഭ്യമാണ്"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"റദ്ദാക്കുക"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ഇപ്പോൾ ഫ്ലിപ്പ് ചെയ്യൂ"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"കൂടുതൽ മികച്ച സെൽഫി ലഭിക്കാൻ ഫോൺ അൺഫോൾഡ് ചെയ്യൂ"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"മികച്ച സെൽഫിക്ക് ഫ്രണ്ട് ഡിസ്പ്ലേയിലേക്ക് മാറണോ?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ഉയർന്ന റെസല്യൂഷൻ ഉള്ള, വീതി കൂടിയ ഫോട്ടോയ്ക്ക്, പിൻഭാഗത്തെ ക്യാമറ ഉപയോഗിക്കുക."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ഈ സ്ക്രീൻ ഓഫാകും"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം അൺഫോൾഡ് ആകുന്നു"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം, കറങ്ങുന്ന വിധത്തിൽ ഫ്ലിപ്പ് ആകുന്നു"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index aa57e81..0540abf 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi унтраалттай байна"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth унтраалттай байна"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Бүү саад бол горим унтраалттай байна"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автомат дүрэм (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апп (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автомат дүрэм эсвэл апп Бүү саад бол горимыг асаасан."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Дамжуулахыг зогсоох"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Аудио гаралт хийх боломжтой төхөөрөмжүүд."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Дууны түвшин"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Нэвтрүүлэлт хэрхэн ажилладаг вэ?"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Нэвтрүүлэлт"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Тохиромжтой Bluetooth төхөөрөмжүүдтэй таны ойролцоох хүмүүс таны нэвтрүүлж буй медиаг сонсох боломжтой"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камер болон микрофон унтраалттай байна"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# мэдэгдэл}other{# мэдэгдэл}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Тэмдэглэл хөтлөх"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Нэвтрүүлэлт"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нэвтрүүлэхээ зогсоох уу?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Хэрэв та <xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлсэн эсвэл гаралтыг өөрчилсөн бол таны одоогийн нэвтрүүлэлтийг зогсооно"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлэх"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Гаралтыг өөрчлөх"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Тодорхойгүй"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g>-г нээх"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Камер аппыг суулгах"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Аппыг тохируулсан"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Дор хаяж нэг төхөөрөмж боломжтой"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Цуцлах"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Одоо хөнтрөх"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Илүү сайн селфи хийхийн тулд утсаа дэлгэнэ үү"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Сайн сельфи авахаар урд талын дэлгэц рүү хөнтрөх үү?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Илүү өндөр нягтаршилтай илүү өргөн зураг авахын тулд арын камерыг ашиглана уу."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Энэ дэлгэц унтарна"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Эвхэгддэг төхөөрөмжийг дэлгэж байна"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Эвхэгддэг төхөөрөмжийг хөнтөрч байна"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 7f3c28c..2a33bc1 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"वाय-फाय बंद आहे"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ब्लूटूथ बंद आहे"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"व्यत्यय आणू नका बंद आहे"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"व्यत्यय आणू नका एका <xliff:g id="ID_1">%s</xliff:g> स्वयंचलित नियमाने सुरू केले."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"व्यत्यय आणू नका (<xliff:g id="ID_1">%s</xliff:g>) ॲपने सुरू केले."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"व्यत्यय आणू नका एका स्वयंचलित नियमाने किंवा ॲपने सुरू केले."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट करणे थांबवा"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ऑडिओ आउटपुटसाठी उपलब्ध डिव्हाइस."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"व्हॉल्यूम"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्टिंग कसे काम करते"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करा"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कंपॅटिबल ब्लूटूथ डिव्हाइस असलेले तुमच्या जवळपासचे लोक हे तुम्ही ब्रॉडकास्ट करत असलेला मीडिया ऐकू शकतात"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कॅमेरा आणि माइक बंद आहेत"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}other{# सूचना}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"नोटटेकिंग"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट करत आहे"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> चे प्रसारण थांबवायचे आहे का?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तुम्ही <xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण केल्यास किंवा आउटपुट बदलल्यास, तुमचे सध्याचे प्रसारण बंद होईल"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण करा"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपूट बदला"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> उघडा"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• कॅमेरा अॅप इंस्टॉल करणे"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• अॅप सेट करणे"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• किमान एक डिव्हाइस उपलब्ध करणे"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करा"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"आता फ्लिप करा"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"आणखी चांगल्या सेल्फीसाठी फोनबद्दल अधिक जाणून घ्या"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"आणखी चांगल्या सेल्फीसाठी फ्रंट डिस्प्ले वापरायचा का?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"उच्च रेझोल्यूशन असलेल्या विस्तृत फोटोसाठी रीअर कॅमेरा वापरा."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ही स्क्रीन बंद होईल"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड करता येण्यासारखे डिव्हाइस अनफोल्ड केले जात आहे"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड करता येण्यासारखे डिव्हाइस आजूबाजूला फ्लिप केले जात आहे"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index bfbc8ea..b595d39 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi dimatikan"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth dimatikan"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Jangan Ganggu dimatikan"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Jangan Ganggu dihidupkan oleh peraturan automatik (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Jangan Ganggu dihidupkan oleh apl (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Jangan Ganggu dihidupkan oleh peraturan automatik atau apl."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Tukar output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Pasang apl kamera"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Apl disediakan"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Sekurang-kurangnya satu peranti tersedia"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Balikkan sekarang"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Buka telefon untuk swafoto yang lebih baik"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Balikkan ke paparan depan utk swafoto lebih baik?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gunakan kamera menghadap belakang untuk mendapatkan foto yang lebih luas dengan resolusi yang lebih tinggi."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Skrin ini akan dimatikan"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Peranti boleh lipat dibuka"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Peranti boleh lipat diterbalikkan"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 909b9ab..627dd77 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -393,10 +393,8 @@
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"အကြောင်းကြားချက်များကို \'မနှောင့်ယှက်ရ\' က ခေတ္တရပ်ထားသည်"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"အကြောင်းကြားချက်များ မရှိ"</string>
- <!-- no translation found for no_unseen_notif_text (395512586119868682) -->
- <skip />
- <!-- no translation found for unlock_to_see_notif_text (7439033907167561227) -->
- <skip />
+ <string name="no_unseen_notif_text" msgid="395512586119868682">"အကြောင်းကြားချက်သစ် မရှိပါ"</string>
+ <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"အကြောင်းကြားချက်ဟောင်းကြည့်ရန် လော့ခ်ဖွင့်ပါ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
@@ -733,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ပိတ်ထားသည်"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ဘလူးတုသ်ကို ပိတ်ထားသည်"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"\"မနှောင့်ယှက်ရ\" ကို ပိတ်ထားသည်"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"မနှောင့်ယှက်ရ\" ကို အလိုအလျောက်စည်းမျဉ်း (<xliff:g id="ID_1">%s</xliff:g>) က ဖွင့်ခဲ့သည်။"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"မနှောင့်ယှက်ရ\" ကို အက်ပ် (<xliff:g id="ID_1">%s</xliff:g>) က ဖွင့်ခဲ့သည်။"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"မနှောင့်ယှက်ရ\" ကို အလိုအလျောက်စည်းမျဉ်းတစ်ခု သို့မဟုတ် အက်ပ်တစ်ခုက ဖွင့်ခဲ့သည်။"</string>
@@ -874,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ကာစ် ရပ်ရန်"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"အသံအထွက်အတွက် ရရှိနိုင်သောစက်များ။"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"အသံအတိုးအကျယ်"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ထုတ်လွှင့်မှုဆောင်ရွက်ပုံ"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ထုတ်လွှင့်ခြင်း"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"အနီးရှိတွဲသုံးနိုင်သော ဘလူးတုသ်သုံးစက် အသုံးပြုသူများက သင်ထုတ်လွှင့်နေသော မီဒီယာကို နားဆင်နိုင်သည်"</string>
@@ -989,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ကင်မရာနှင့် မိုက် ပိတ်ထားသည်"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{အကြောင်းကြားချက် # ခု}other{အကြောင်းကြားချက် # ခု}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>၊ <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"မှတ်စုလိုက်ခြင်း"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ထုတ်လွှင့်ခြင်း"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ထုတ်လွှင့်ခြင်းကို ရပ်မလား။"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ကို ထုတ်လွှင့်သောအခါ (သို့) အထွက်ကို ပြောင်းသောအခါ သင့်လက်ရှိထုတ်လွှင့်ခြင်း ရပ်သွားမည်"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ထုတ်လွှင့်ခြင်း"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"အထွက်ကို ပြောင်းခြင်း"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"မသိ"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE၊ MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ဖွင့်ရန်"</string>
@@ -1007,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ကင်မရာအက်ပ် ထည့်သွင်းထားရမည်"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• အက်ပ်ကို စနစ်ထည့်သွင်းထားရမည်"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• အနည်းဆုံး စက်တစ်ခုသုံးနိုင်ရမည်"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"မလုပ်တော့"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ယခုလှည့်လိုက်ပါ"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ပိုကောင်းသော ဆယ်လ်ဖီအတွက် ဖုန်းကိုဖြန့်လိုက်ပါ"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ပိုကောင်းသော ဆယ်လ်ဖီအတွက် ဖန်သားပြင်ကိုလှည့်မလား။"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ပုံရိပ်ပြတ်သားကိန်း ပိုမြင့်ပြီး မြင်ကွင်းပိုကျယ်သည့် ဓာတ်ပုံအတွက် နောက်ဘက်ကင်မရာကို အသုံးပြုပါ။"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ဤဖန်သားပြင်ကို ပိတ်လိုက်မည်"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ခေါက်နိုင်သောစက်ကို ဖြန့်လိုက်သည်"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ခေါက်နိုင်သောစက်ကို တစ်ဘက်သို့ လှန်လိုက်သည်"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 95846f0..8dbdd2f 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wifi er av"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth er av"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Ikke forstyrr er av"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Ikke forstyrr ble slått på av en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Ikke forstyrr ble slått på av en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Ikke forstyrr ble slått på av en automatisk regel eller en app."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stopp castingen"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Tilgjengelige enheter for lydutgang."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volum"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Slik fungerer kringkasting"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Kringkasting"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Folk i nærheten med kompatible Bluetooth-enheter kan lytte til mediene du kringkaster"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er av"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# varsel}other{# varsler}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Notatskriving"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Kringkaster"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vil du stoppe kringkastingen av <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du kringkaster <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller endrer utgangen, stopper den nåværende kringkastingen din"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Kringkast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Endre utgang"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukjent"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Åpne <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• en kameraapp er installert"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• appen er konfigurert"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• minst én enhet er tilgjengelig"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vend nå"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Brett ut telefonen for å ta bedre selfier"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vil du bytte til frontskjermen for bedre selfier?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Bruk det bakovervendte kameraet for å ta bredere bilder med høyere oppløsning."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Denne skjermen slås av"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En sammenleggbar enhet blir brettet ut"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En sammenleggbar enhet blir snudd"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index b04e368..00e52a1 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -500,8 +500,7 @@
<string name="wallet_error_generic" msgid="257704570182963611">"तपाईंका कार्डहरू प्राप्त गर्ने क्रममा समस्या भयो, कृपया पछि फेरि प्रयास गर्नुहोस्"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"लक स्क्रिनसम्बन्धी सेटिङ"</string>
<string name="qr_code_scanner_title" msgid="1938155688725760702">"QR कोड स्क्यानर"</string>
- <!-- no translation found for qr_code_scanner_updating_secondary_label (8344598017007876352) -->
- <skip />
+ <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"अपडेट गरिँदै छ"</string>
<string name="status_bar_work" msgid="5238641949837091056">"कार्य प्रोफाइल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"हवाइजहाज मोड"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"तपाईँले आफ्नो अर्को अलार्म <xliff:g id="WHEN">%1$s</xliff:g> सुन्नुहुने छैन"</string>
@@ -732,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi‑Fi अफ छ"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ब्लुटुथ निष्क्रिय छ"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"बाधा नपुर्याउनुहोस् नामक विकल्प निष्क्रिय छ"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"कुनै स्वचालित नियमले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रियो गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"कुनै अनुप्रयोगले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"कुनै स्वचालित नियम वा अनुप्रयोगले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो।"</string>
@@ -873,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट गर्न छाड्नुहोस्"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"अडियो आउटपुटका लागि उपलब्ध डिभाइसहरू।"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"भोल्युम"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"प्रसारण गर्ने सुविधाले कसरी काम गर्छ"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"प्रसारण"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कम्प्याटिबल ब्लुटुथ डिभाइस भएका नजिकैका मान्छेहरू तपाईंले प्रसारण गरिरहनुभएको मिडिया सुन्न सक्छन्"</string>
@@ -988,30 +988,23 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"क्यामेरा र माइक अफ छन्"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# वटा सूचना}other{# वटा सूचनाहरू}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"टिपोट गर्ने कार्य"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"प्रसारण गरिँदै छ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ब्रोडकास्ट गर्न छाड्ने हो?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तपाईंले <xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुभयो वा आउटपुट परिवर्तन गर्नुभयो भने तपाईंको हालको ब्रोडकास्ट रोकिने छ"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुहोस्"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट परिवर्तन गर्नुहोस्"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
- <!-- no translation found for keyguard_affordance_enablement_dialog_action_template (8164857863036314664) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_message (2790910660524887941) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_wallet_instruction_1 (8439655049139819278) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_wallet_instruction_2 (4321089250629477835) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_qr_scanner_instruction (5355839079232119791) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_home_instruction_1 (8438311171750568633) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_home_instruction_2 (8308525385889021652) -->
+ <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> खोल्नुहोस्"</string>
+ <string name="keyguard_affordance_enablement_dialog_message" msgid="2790910660524887941">"<xliff:g id="APPNAME">%1$s</xliff:g> एपलाई सर्टकटका रूपमा हाल्न, निम्न कुराको सुनिश्चित गर्नुहोस्:"</string>
+ <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• एप सेटअप गरिएको छ"</string>
+ <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet मा कम्तीमा एउटा कार्ड हालिएको छ"</string>
+ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• क्यामेरा एप इन्स्टल गरिएको छ"</string>
+ <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• एप सेटअप गरिएको छ"</string>
+ <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• कम्तीमा एउटा डिभाइस उपलब्ध छ"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
<skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द गर्नुहोस्"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"अहिले नै फ्लिप गर्नुहोस्"</string>
@@ -1019,8 +1012,8 @@
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"अझ राम्रो सेल्फी खिच्न फ्लिप गरी अगाडिपट्टिको डिस्प्ले प्रयोग गर्ने हो?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"अझ बढी रिजोल्युसन भएको फराकिलो फोटो खिच्न पछाडिपट्टिको क्यामेरा प्रयोग गर्नुहोस्।"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ यो स्क्रिन अफ हुने छ"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड गर्न मिल्ने डिभाइस अनफोल्ड गरेको देखाइएको एनिमेसन"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड गर्न मिल्ने डिभाइस यताउता पल्टाएर देखाइएको एनिमेसन"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 0c05b12..6171235 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wifi staat uit"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth staat uit"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Niet storen staat uit"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Niet storen is aangezet door een automatische regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Niet storen is aangezet door een app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Niet storen is aangezet door een automatische regel of app."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Casten stoppen"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Beschikbare apparaten voor audio-uitvoer."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitzenden werkt"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Uitzending"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mensen bij jou in de buurt met geschikte bluetooth-apparaten kunnen luisteren naar de media die je uitzendt"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera en microfoon staan uit"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# melding}other{# meldingen}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Aantekeningen maken"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitzending"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Uitzending van <xliff:g id="APP_NAME">%1$s</xliff:g> stopzetten?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Als je <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzendt of de uitvoer wijzigt, wordt je huidige uitzending gestopt"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzenden"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Uitvoer wijzigen"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d mmm"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"u:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> openen"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Er moet een camera-app zijn geïnstalleerd"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• De app is ingesteld"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Er is ten minste één apparaat beschikbaar"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuleren"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Nu omkeren"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Klap de telefoon open voor een betere selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Omkeren naar scherm voorkant voor een betere selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gebruik de camera aan de achterzijde voor een bredere foto met hogere resolutie."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Dit scherm gaat uit"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Opvouwbaar apparaat wordt uitgevouwen"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Opvouwbaar apparaat wordt gedraaid"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 307b7b9..40b335a 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"ୱାଇ-ଫାଇ ବନ୍ଦ ଅଛି"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ବ୍ଲୁଟୂଥ୍ ଅଫ୍ ଅଛି"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅଫ୍ ଅଛି"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ଏକ (<xliff:g id="ID_1">%s</xliff:g>) ନିୟମ ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ସ୍ୱଚାଳିତ ଭାବେ ଅନ୍ କରାଗଲା।"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ଏକ ଆପ୍ (<xliff:g id="ID_1">%s</xliff:g>) ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍ କରାଗଲା।"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ଏକ ସ୍ୱଚାଳିତ ନିୟମ କିମ୍ବା ଆପ୍ ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍ କରାଗଲା।"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ଅଡିଓ ଆଉଟପୁଟ ପାଇଁ ଉପଲବ୍ଧ ଡିଭାଇସଗୁଡ଼ିକ।"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ଭଲ୍ୟୁମ"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ବ୍ରଡକାଷ୍ଟିଂ କିପରି କାମ କରେ"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ବ୍ରଡକାଷ୍ଟ"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ଆପଣଙ୍କ ଆଖପାଖର କମ୍ପାଟିବଲ ବ୍ଲୁଟୁଥ ଡିଭାଇସ ଥିବା ଲୋକମାନେ ଆପଣ ବ୍ରଡକାଷ୍ଟ କରୁଥିବା ମିଡିଆ ଶୁଣିପାରିବେ"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"କ୍ୟାମେରା ଏବଂ ମାଇକ ବନ୍ଦ ଅଛି"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#ଟି ବିଜ୍ଞପ୍ତି}other{#ଟି ବିଜ୍ଞପ୍ତି}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"ନୋଟଟେକିଂ"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ବ୍ରଡକାଷ୍ଟ କରୁଛି"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ଯଦି ଆପଣ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତି କିମ୍ବା ଆଉଟପୁଟ ବଦଳାନ୍ତି, ତେବେ ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ବ୍ରଡକାଷ୍ଟ ବନ୍ଦ ହୋଇଯିବ"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତୁ"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ଆଉଟପୁଟ ବଦଳାନ୍ତୁ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ଅଜଣା"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ଖୋଲନ୍ତୁ"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ଏକ କେମେରା ଆପ ଇନଷ୍ଟଲ କରିବା"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ଆପ ସେଟ ଅପ କରାଯାଇଛି"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ଅତିକମରେ ଗୋଟିଏ ଡିଭାଇସ ଉପଲବ୍ଧ ଅଛି"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ବର୍ତ୍ତମାନ ଫ୍ଲିପ କରନ୍ତୁ"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ଏକ ଉନ୍ନତ ସେଲ୍ଫି ପାଇଁ ଫୋନକୁ ଅନଫୋଲ୍ଡ କରନ୍ତୁ"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ଏକ ଉନ୍ନତ ସେଲ୍ଫି ପାଇଁ ସାମ୍ନା ଡିସପ୍ଲେକୁ ଫ୍ଲିପ କରିବେ?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ଉଚ୍ଚ ରିଜୋଲ୍ୟୁସନ ସହ ଅଧିକ ଚଉଡ଼ାର ଏକ ଫଟୋ ନେବା ପାଇଁ ପଛ-ପଟର କେମେରା ବ୍ୟବହାର କରନ୍ତୁ।"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ଏହି ସ୍କ୍ରିନ ବନ୍ଦ ହୋଇଯିବ"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଅନଫୋଲ୍ଡ କରାଯାଉଛି"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଫ୍ଲିପ କରାଯାଉଛି"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index ccf27d7..b6d9121 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"ਵਾਈ-ਫਾਈ ਬੰਦ ਹੈ"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ਬਲੂਟੁੱਥ ਬੰਦ ਹੈ"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਬੰਦ ਹੈ"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ਸਵੈਚਲਿਤ ਨਿਯਮ (<xliff:g id="ID_1">%s</xliff:g>) ਦੁਆਰਾ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ਐਪ (<xliff:g id="ID_1">%s</xliff:g>) ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ਇੱਕ ਸਵੈਚਲਿਤ ਨਿਯਮ ਜਾਂ ਐਪ ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ਆਡੀਓ ਆਊਟਪੁੱਟ ਲਈ ਉਪਲਬਧ ਡੀਵਾਈਸ।"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ਅਵਾਜ਼"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ਪ੍ਰਸਾਰਨ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ਪ੍ਰਸਾਰਨ"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ਅਨੁਰੂਪ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਨਜ਼ਦੀਕੀ ਲੋਕ ਤੁਹਾਡੇ ਵੱਲੋਂ ਪ੍ਰਸਾਰਨ ਕੀਤੇ ਜਾ ਰਹੇ ਮੀਡੀਆ ਨੂੰ ਸੁਣ ਸਕਦੇ ਹਨ"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ ਬੰਦ ਹਨ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ਸੂਚਨਾ}one{# ਸੂਚਨਾ}other{# ਸੂਚਨਾਵਾਂ}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"ਨੋਟ ਬਣਾਉਣਾ"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ਪ੍ਰਸਾਰਨ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਦੇ ਪ੍ਰਸਾਰਨ ਨੂੰ ਰੋਕਣਾ ਹੈ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ਜੇ ਤੁਸੀਂ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰਦੇ ਹੋ ਜਾਂ ਆਊਟਪੁੱਟ ਬਦਲਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਪ੍ਰਸਾਰਨ ਰੁਕ ਜਾਵੇਗਾ"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰੋ"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ਆਊਟਪੁੱਟ ਬਦਲੋ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ਅਗਿਆਤ"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ਕੈਮਰਾ ਐਪ ਸਥਾਪਤ ਕਰੋ"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ਐਪ ਦਾ ਸੈੱਟਅੱਪ ਹੋ ਗਿਆ ਹੈ"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ਘੱਟੋ-ਘੱਟ ਇੱਕ ਡੀਵਾਈਸ ਉਪਲਬਧ ਹੈ"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ਰੱਦ ਕਰੋ"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ਹੁਣੇ ਫਲਿੱਪ ਕਰੋ"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ਬਿਹਤਰ ਸੈਲਫ਼ੀ ਲਈ ਫ਼ੋਨ ਨੂੰ ਖੋਲ੍ਹੋ"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ਕੀ ਬਿਹਤਰ ਸੈਲਫ਼ੀ ਲਈ ਅਗਲੀ ਡਿਸਪਲੇ \'ਤੇ ਫਲਿੱਪ ਕਰਨਾ ਹੈ?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ਉੱਚ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਵਾਲੀ ਜ਼ਿਆਦਾ ਚੌੜੀ ਫ਼ੋਟੋ ਲਈ ਪਿਛਲੇ ਕੈਮਰੇ ਦੀ ਵਰਤੋਂ ਕਰੋ।"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ਇਹ ਸਕ੍ਰੀਨ ਬੰਦ ਹੋ ਜਾਵੇਗੀ"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਆਲੇ-ਦੁਆਲੇ ਫਲਿੱਪ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c82f75c..5f71cc6 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi jest wyłączone"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth jest wyłączony"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Tryb Nie przeszkadzać jest wyłączony"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Tryb Nie przeszkadzać został włączony przez aplikację (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną lub aplikację."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zatrzymaj przesyłanie"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostępne urządzenia do odtwarzania dźwięku."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Głośność"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak działa transmitowanie"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Transmisja"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osoby w pobliżu ze zgodnymi urządzeniami Bluetooth mogą słuchać transmitowanych przez Ciebie multimediów"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Aparat i mikrofon są wyłączone"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# powiadomienie}few{# powiadomienia}many{# powiadomień}other{# powiadomienia}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Notatki"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmisja"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zatrzymaj transmisję aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jeśli transmitujesz aplikację <xliff:g id="SWITCHAPP">%1$s</xliff:g> lub zmieniasz dane wyjściowe, Twoja obecna transmisja zostanie zakończona"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmisja aplikacji <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmień dane wyjściowe"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Brak informacji"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otwórz: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Zainstalowano aplikację aparatu."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacja została skonfigurowana."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostępne jest co najmniej 1 urządzenie."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anuluj"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Przełącz teraz"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozłóż telefon, aby uzyskać lepszej jakości selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Przełączyć na przedni wyświetlacz?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Użyj tylnego aparatu, aby zrobić szersze zdjęcie o większej rozdzielczości."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Ekran się wyłączy"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Składane urządzenie jest rozkładane"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Składane urządzenie jest obracane"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index f6a1c5c..11a4c69 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"O Wi-Fi está desativado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"O recurso Não perturbe está desativado"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O recurso Não perturbe foi ativado por uma regra automática ou app."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Um app de câmera está instalado"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• O app está disponível"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Usar o display frontal para tirar uma selfie melhor?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use a câmera traseira para tirar uma foto mais ampla e com maior resolução."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta tela vai ser desativada"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 98b5c76..30410fd 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desativado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Não incomodar desativado"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O modo Não incomodar foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O modo Não incomodar foi ativado por uma app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O modo Não incomodar foi ativado por uma regra automática ou por uma app."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponíveis para a saída de áudio."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Transmissão"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas de si com dispositivos Bluetooth compatíveis podem ouvir o conteúdo multimédia que está a transmitir"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmara e o microfone estão desativados"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}many{# notificações}other{# notificações}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Tomar notas"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"A transmitir"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão da app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se transmitir a app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou alterar a saída, a sua transmissão atual é interrompida"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmita a app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Altere a saída"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecida"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Instale uma app de câmara"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• A app está configurada"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Está disponível, pelo menos, um dispositivo"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Inverter agora"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desdobre o telemóvel para uma selfie melhor"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Inverter para ecrã frontal para uma selfie melhor?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use a câmara traseira para uma foto mais ampla com uma resolução superior."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Este ecrã vai ser desligado"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável a ser desdobrado"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável a ser virado ao contrário"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index f6a1c5c..11a4c69 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"O Wi-Fi está desativado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"O recurso Não perturbe está desativado"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O recurso Não perturbe foi ativado por uma regra automática ou app."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Um app de câmera está instalado"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• O app está disponível"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Usar o display frontal para tirar uma selfie melhor?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use a câmera traseira para tirar uma foto mais ampla e com maior resolução."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta tela vai ser desativada"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index e9257fb..86f6205 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Conexiunea Wi-Fi este dezactivată"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Funcția Bluetooth este dezactivată"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Funcția Nu deranja este dezactivată"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Funcția Nu deranja a fost activată de o regulă automată (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Funcția Nu deranja a fost activată de o aplicație (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Funcția Nu deranja a fost activată de o regulă automată sau de o aplicație."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmite <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Schimbă rezultatul"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Necunoscută"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE, z LLL"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Deschide <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Instalează o aplicație pentru camera foto"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplicația este configurată"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Este disponibil cel puțin un dispozitiv"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulează"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Întoarce-l acum"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desfă telefonul pentru un selfie mai bun"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Comuți la ecranul frontal pentru un selfie mai bun?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Folosește camera posterioară pentru o fotografie mai lată, cu rezoluție mai mare."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Acest ecran se va dezactiva"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispozitiv pliabil care este desfăcut"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispozitiv pliabil care este întors"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 5128e0e..28d5f40 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Модуль Wi-Fi отключен"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Модуль Bluetooth отключен"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не беспокоить\" отключен"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режим \"Не беспокоить\" был включен специальным правилом (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Режим \"Не беспокоить\" был включен приложением (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Режим \"Не беспокоить\" был включен специальным правилом или приложением."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Транслировать на другое устройство"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Открыть \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Установлено приложение камеры."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Приложение установлено."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Доступно хотя бы одно устройство."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отмена"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернуть сейчас"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Разложите телефон, чтобы селфи получилось лучше"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Перевернули телефон передним экраном к себе?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Используйте основную камеру с широкоугольным объективом и высоким разрешением."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Этот экран отключится"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складное устройство в разложенном виде"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перевернутое складное устройство"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index f176795..f7cdcb10 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ක්රියා විරහිතයි"</string>
<string name="bt_is_off" msgid="7436344904889461591">"බ්ලූටූත් ක්රියා විරහිතයි"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"බාධා නොකරන්න ක්රියා විරහිතයි"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ස්වයංක්රිය රීතියක් මගින් බාධා නොකරන්න ක්රියාත්මක කරන ලදී (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"යෙදුමක් මගින් බාධා නොකරන්න ක්රියාත්මක කරන ලදී (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ස්වයංක්රිය රීතියක් හෝ යෙදුමක් මගින් බාධා නොකරන්න ක්රියාත්මක කරන ලදී."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"විකාශය නවතන්න"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ශ්රව්ය ප්රතිදානය සඳහා තිබෙන උපාංග."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"හඬ පරිමාව"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"විකාශනය ක්රියා කරන ආකාරය"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"විකාශනය"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ගැළපෙන බ්ලූටූත් උපාංග සහිත ඔබ අවට සිටින පුද්ගලයින්ට ඔබ විකාශනය කරන මාධ්යයට සවන් දිය හැකිය"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"කැමරාව සහ මයික් ක්රියාවිරහිතයි"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{දැනුම්දීම් #ක්}one{දැනුම්දීම් #ක්}other{දැනුම්දීම් #ක්}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"සටහන් කර ගැනීම"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"විකාශනය කරමින්"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> විකාශනය කිරීම නවත්වන්නද?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ඔබ <xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය කළහොත් හෝ ප්රතිදානය වෙනස් කළහොත්, ඔබගේ වත්මන් විකාශනය නවතිනු ඇත."</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ප්රතිදානය වෙනස් කරන්න"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"නොදනී"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> විවෘත කරන්න"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• කැමරා යෙදුමක් ස්ථාපන කරන්න"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• යෙදුම සකසා ඇත"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• අවම වශයෙන් එක උපාංගයක් ලැබේ"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"අවලංගු කරන්න"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"දැන් පෙරළන්න"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"වඩා හොඳ සෙල්ෆියක් සඳහා දුරකථනය දිගහරින්න"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"වඩා හොඳ සෙල්ෆියක් සඳහා ඉදිරිපස සංදර්ශකයට පෙරළන්න ද?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ඉහළ විභේදන සහිත පුළුල් ඡායාරූපයක් සඳහා පසුපසට මුහුණලා ඇති කැමරාව භාවිතා කරන්න."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ මෙම තිරය ක්රියා විරහිත වනු ඇත"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"දිග හැරෙමින් පවතින නැමිය හැකි උපාංගය"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"වටා පෙරළෙමින් තිබෙන නැමිය හැකි උපාංගය"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index e4c978b..b2586f1 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Pripojenie Wi‑Fi je vypnuté"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Rozhranie Bluetooth je vypnuté"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Režim bez vyrušení je vypnutý"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režim bez vyrušení bol zapnutý automatickým pravidlom (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režim bez vyrušení bol zapnutý aplikáciou (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režim bez vyrušení bol zapnutý automatickým pravidlom alebo aplikáciou."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysielanie aplikácie <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmena výstupu"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznáme"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvoriť <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Nainštalujte si aplikáciu kamery"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikácia je nastavená"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• K dispozícii je minimálne jedno zariadenie"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušiť"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Prevráťte"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ak chcete lepšie selfie, rozložte telefón"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Prevrátiť na pred. obrazovku pre lepšie selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Pomocou zadného fotoaparátu vytvorte širšiu fotku s vyšším rozlíšením."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Táto obrazovka sa vypne"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozloženie skladacieho zariadenia"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Prevrátenie skladacieho zariadenia"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index ef5e63a..a52fede 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je izklopljen."</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je izklopljen"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Način »ne moti« je izklopljen"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Samodejno pravilo (<xliff:g id="ID_1">%s</xliff:g>) je vklopilo način »ne moti«."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je vklopila način »ne moti«."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način »ne moti« je bil vklopljen zaradi samodejnega pravila ali aplikacije."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ustavi predvajanje"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Razpoložljive naprave za zvočni izhod"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Glasnost"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako deluje oddajanje"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Oddajanje"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osebe v bližini z združljivo napravo Bluetooth lahko poslušajo predstavnost, ki jo oddajate."</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat in mikrofon sta izklopljena."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obvestilo}one{# obvestilo}two{# obvestili}few{# obvestila}other{# obvestil}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Ustvarjanje zapiskov"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Oddajanje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite ustaviti oddajanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Če oddajate aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g> ali spremenite izhod, bo trenutno oddajanje ustavljeno."</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Oddajaj aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Sprememba izhoda"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznano"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Odpri aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Namestite fotografsko aplikacijo."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacija mora biti nastavljena."</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Na voljo mora biti vsaj ena naprava."</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Prekliči"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrnite"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Razprite telefon za boljši selfi"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Obrnite telefon na sprednji zaslon za boljši selfi"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Uporabite hrbtni fotoaparat, da posnamete širšo sliko višje ločljivosti."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ta zaslon se bo izklopil."</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Razpiranje zložljive naprave"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Obračanje zložljive naprave"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 24e2616..e9ae54a 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi është joaktiv"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth-i është joaktiv"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Modaliteti \"Mos shqetëso\" është joaktiv"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një aplikacion (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik ose një aplikacion."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmeto <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ndrysho daljen"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"I panjohur"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Hap \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Të instalosh një aplikacion të kamerës"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacioni është konfiguruar"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ofrohet të paktën një pajisje"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulo"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"U kthye tani"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Shpalos telefonin për një selfi më të mirë"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Të kthehet tek ekrani para për selfi më të mirë?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Përdor lenten e kamerës së pasme për një fotografi më të gjerë me rezolucion më të lartë."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ky ekran do të fiket"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Pajisja e palosshme duke u hapur"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Pajisja e palosshme duke u rrotulluar"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 9464ac5..f3c3de3 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"WiFi је искључен"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth је искључен"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Режим Не узнемиравај је искључен"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Аутоматско правило (<xliff:g id="ID_1">%s</xliff:g>) је укључило режим Не узнемиравај."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апликација (<xliff:g id="ID_1">%s</xliff:g>) је укључила режим Не узнемиравај."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Аутоматско правило или апликација су укључили режим Не узнемиравај."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промените излаз"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"ДДД, д. МММ"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"с:мин"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ч:мин"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворите: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• да сте инсталирали апликацију за камеру"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• да је апликација подешена"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• да је доступан барем један уређај"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обрните"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворите телефон за бољи селфи"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Желите да обрнете на предњи екран за бољи селфи?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Користите задњу камеру да бисте снимили ширу слику са вишом резолуцијом."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Овај екран ће се искључити"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Уређај на преклоп се отвара"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Уређај на преклоп се обрће"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index f5cf437..ae40b7b 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"wifi är inaktiverat"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth är inaktiverat"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Stör ej är inaktiverat"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Stör ej aktiverades via en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Stör ej aktiverades via en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Stör ej aktiverades via en automatisk regel eller en app."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sluta casta"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Enheter som är tillgängliga för ljudutdata."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volym"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Så fungerar utsändning"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Utsändning"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i närheten med kompatibla Bluetooth-enheter kan lyssna på medieinnehåll som du sänder ut"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kameran och mikrofonen är avstängda"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# avisering}other{# aviseringar}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Anteckningar"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sänder"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vill du sluta sända från <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Om en utsändning från <xliff:g id="SWITCHAPP">%1$s</xliff:g> pågår eller om du byter ljudutgång avbryts den nuvarande utsändningen"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sänd från <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Byt ljudutgång"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Okänt"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h.mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Öppna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• installera en kameraapp"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• appen har konfigurerats"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• minst en enhet är tillgänglig"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vänd nu"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vik upp telefonen för att ta en bättre selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vill du ta en bättre selfie med främre skärmen?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Använd den bakre kameran för att ta ett mer vidsträckt foto med högre upplösning."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Den här skärmen inaktiveras"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En vikbar enhet viks upp"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En vikbar enhet vänds"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index e0043e3..f13afb8 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi imezimwa"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth imezimwa"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Kipengele cha Usinisumbue kimezimwa"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki <xliff:g id="ID_1">%s</xliff:g>."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Kipengele cha usinisumbue kimewashwa na programu (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki au programu."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Acha kutuma"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Vifaa vya kutoa sauti vilivyopo"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Sauti"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jinsi utangazaji unavyofanya kazi"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Tangaza"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Watu walio karibu nawe wenye vifaa oanifu vya Bluetooth wanaweza kusikiliza maudhui unayoyatangaza"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera na maikrofoni zimezimwa"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Arifa #}other{Arifa #}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Kuandika vidokezo"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Inaarifu"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ungependa kusimamisha utangazaji kwenye <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ikiwa unatangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g> au unabadilisha maudhui, tangazo lako la sasa litasimamishwa"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Tangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Badilisha maudhui"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Haijulikani"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"saa:dk"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dk"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Fungua <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Sakinisha programu ya kamera"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Programu hii imewekewa mipangilio"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Angalau kifaa kimoja kinapatikana"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ghairi"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Geuza kifaa sasa"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Kunjua simu ili upige selfi iliyo bora"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Ungependa kugeuza skrini ya mbele ili upige selfi?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Tumia kamera ya nyuma ili upige picha pana iliyo na ubora wa juu."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Skrini hii itajizima"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Kifaa kinachokunjwa kikikunjuliwa"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Kifaa kinachokunjwa kikigeuzwa"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index f800cd0..ef01766 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"வைஃபை முடக்கத்தில் உள்ளது"</string>
<string name="bt_is_off" msgid="7436344904889461591">"புளூடூத் முடக்கத்தில் உள்ளது"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"\"தொந்தரவு செய்ய வேண்டாம்\" முடக்கத்தில் உள்ளது"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, ஆப்ஸ் (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி அல்லது ஆப்ஸ் இயக்கியுள்ளது."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"அலைபரப்புவதை நிறுத்து"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ஆடியோ அவுட்புட்டுக்குக் கிடைக்கும் சாதனங்கள்."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ஒலியளவு"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"பிராட்காஸ்ட் எவ்வாறு செயல்படுகிறது?"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"பிராட்காஸ்ட்"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"நீங்கள் பிராட்காஸ்ட் செய்யும் மீடியாவை அருகிலுள்ளவர்கள் இணக்கமான புளூடூத் சாதனங்கள் மூலம் கேட்கலாம்"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"கேமராவும் மைக்கும் ஆஃப் செய்யப்பட்டுள்ளன"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# அறிவிப்பு}other{# அறிவிப்புகள்}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"குறிப்பெடுத்தல்"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ஒலிபரப்புதல்"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒலிபரப்பப்படுவதை நிறுத்தவா?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"நீங்கள் <xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பினாலோ அவுட்புட்டை மாற்றினாலோ உங்களின் தற்போதைய ஒலிபரப்பு நிறுத்தப்படும்"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பு"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"அவுட்புட்டை மாற்று"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"தெரியவில்லை"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸைத் திற"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• கேமரா ஆப்ஸ் நிறுவப்பட்டிருக்க வேண்டும்"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• இந்த ஆப்ஸ் அமைக்கப்பட்டிருக்க வேண்டும்"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• குறைந்தபட்சம் ஒரு சாதனமாவது கிடைக்க வேண்டும்"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ரத்துசெய்"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"இப்போது மாற்றவும்"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"சிறந்த செல்ஃபிக்கு மொபைலை மடக்காதீர்கள்"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"சிறந்த செல்ஃபிக்கு முன்புற டிஸ்பிளேவிற்கு மாற்றவா?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"அதிகத் தெளிவுத்திறனுடன் அகலக் கோணத்தில் படத்தை எடுப்பதற்குப் பின்பக்கக் கேமராவைப் பயன்படுத்துங்கள்."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ இந்தத் திரை ஆஃப் ஆகிவிடும்"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"மடக்கத்தக்க சாதனம் திறக்கப்படுகிறது"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"மடக்கத்தக்க சாதனம் ஃபிளிப் செய்யப்பட்டு திருப்பப்படுகிறது"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index f707088..2a2bba5 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -66,7 +66,7 @@
<string name="usb_contaminant_title" msgid="894052515034594113">"USB పోర్ట్ నిలిపివేయబడింది"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"మీ పరికరంలోకి నీరు లేదా చెత్తాచెదారం చేరిపోకుండా కాపాడటానికి, USB పోర్ట్ నిలిపివేయబడుతుంది, అలాగే యాక్సెసరీలు వేటిని గుర్తించదు.\n\nUSB పోర్ట్ను ఉపయోగించడం సురక్షితమేనని నిర్ధారించుకున్న తర్వాత, మళ్లీ మీకో నోటిఫికేషన్ రూపంలో తెలియజేయబడుతుంది."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ఛార్జర్లు, యాక్సెసరీలను గుర్తించే విధంగా USB పోర్ట్ ప్రారంభించబడింది"</string>
- <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USBని ప్రారంభించు"</string>
+ <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USBని ప్రారంభించండి"</string>
<string name="learn_more" msgid="4690632085667273811">"మరింత తెలుసుకోండి"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"స్క్రీన్షాట్"</string>
<string name="global_action_smart_lock_disabled" msgid="9097102067802412936">"Smart Lock డిజేబుల్ చేయబడింది"</string>
@@ -105,7 +105,7 @@
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"మీ పరికరం నుండి వచ్చే మ్యూజిక్, కాల్స్, రింగ్టోన్ల వంటి ధ్వనులు"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"మైక్రోఫోన్"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"పరికరం ఆడియో, మైక్రోఫోన్"</string>
- <string name="screenrecord_start" msgid="330991441575775004">"ప్రారంభించు"</string>
+ <string name="screenrecord_start" msgid="330991441575775004">"ప్రారంభించండి"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"స్క్రీన్ రికార్డింగ్ చేయబడుతోంది"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"స్క్రీన్, ఆడియో రికార్డింగ్ చేయబడుతున్నాయి"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"స్క్రీన్పై తాకే స్థానాలను చూపు"</string>
@@ -289,7 +289,7 @@
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC నిలిపివేయబడింది"</string>
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ప్రారంభించబడింది"</string>
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"స్క్రీన్ రికార్డ్"</string>
- <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ప్రారంభించు"</string>
+ <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ప్రారంభించండి"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ఆపు"</string>
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"వన్-హ్యాండెడ్ మోడ్"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"పరికరం మైక్రోఫోన్ను అన్బ్లాక్ చేయమంటారా?"</string>
@@ -356,8 +356,8 @@
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్లోని అన్ని యాప్లు మరియు డేటా తొలగించబడతాయి."</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"గెస్ట్కు తిరిగి స్వాగతం!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"మీరు మీ సెషన్ని కొనసాగించాలనుకుంటున్నారా?"</string>
- <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించు"</string>
- <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"అవును, కొనసాగించు"</string>
+ <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించండి"</string>
+ <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"అవును, కొనసాగించండి"</string>
<string name="guest_notification_app_name" msgid="2110425506754205509">"గెస్ట్ మోడ్"</string>
<string name="guest_notification_session_active" msgid="5567273684713471450">"మీరు గెస్ట్ మోడ్లో ఉన్నారు"</string>
<string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"కొత్త యూజర్ను జోడించడం వలన గెస్ట్ మోడ్ నుండి వైదొలుగుతుంది. అలాగే ప్రస్తుత గెస్ట్ సెషన్ నుండి అన్ని యాప్లతో పాటు మొత్తం డేటా తొలగించబడుతుంది."</string>
@@ -391,7 +391,7 @@
<string name="notification_section_header_conversations" msgid="821834744538345661">"సంభాషణలు"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"అన్ని నిశ్శబ్ద నోటిఫికేషన్లను క్లియర్ చేస్తుంది"</string>
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"అంతరాయం కలిగించవద్దు ద్వారా నోటిఫికేషన్లు పాజ్ చేయబడ్డాయి"</string>
- <string name="media_projection_action_text" msgid="3634906766918186440">"ఇప్పుడే ప్రారంభించు"</string>
+ <string name="media_projection_action_text" msgid="3634906766918186440">"ఇప్పుడే ప్రారంభించండి"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"నోటిఫికేషన్లు లేవు"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"కొత్త నోటిఫికేషన్లు ఏవీ లేవు"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"పాత నోటిఫికేషన్ల కోసం అన్లాక్ చేయండి"</string>
@@ -442,7 +442,7 @@
<string name="volume_odi_captions_tip" msgid="8825655463280990941">"మీడియాకు ఆటోమేటిక్ క్యాప్షన్లు"</string>
<string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"క్యాప్షన్ల చిట్కాను మూసివేయండి"</string>
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"క్యాప్షన్లు ఓవర్లే"</string>
- <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"ప్రారంభించు"</string>
+ <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"ప్రారంభించండి"</string>
<string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"నిలిపివేయండి"</string>
<string name="sound_settings" msgid="8874581353127418308">"సౌండ్ & వైబ్రేషన్"</string>
<string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"సెట్టింగ్లు"</string>
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ఆఫ్లో ఉంది"</string>
<string name="bt_is_off" msgid="7436344904889461591">"బ్లూటూత్ ఆఫ్లో ఉంది"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"అంతరాయం కలిగించవద్దు ఆఫ్లో ఉంది"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ఆటోమేటిక్ నియమం (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"యాప్ (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ఆటోమేటిక్ నియమం లేదా యాప్ ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ప్రసారాన్ని ఆపివేయండి"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ఆడియో అవుట్పుట్ కోసం అందుబాటులో ఉన్న పరికరాలు."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"వాల్యూమ్"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ప్రసారం కావడం అనేది ఎలా పని చేస్తుంది"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ప్రసారం"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"మీకు సమీపంలో ఉన్న వ్యక్తులు అనుకూలత ఉన్న బ్లూటూత్ పరికరాలతో మీరు ప్రసారం చేస్తున్న మీడియాను వినగలరు"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"కెమెరా, మైక్ ఆఫ్లో ఉన్నాయి"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# నోటిఫికేషన్}other{# నోటిఫికేషన్లు}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"నోట్టేకింగ్"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ప్రసారం చేస్తోంది"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రసారం చేయడాన్ని ఆపివేయాలా?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"మీరు <xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేస్తే లేదా అవుట్పుట్ను మార్చినట్లయితే, మీ ప్రస్తుత ప్రసారం ఆగిపోతుంది"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేయండి"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"అవుట్పుట్ను మార్చండి"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"తెలియదు"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g>ను తెరవండి"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• కెమెరా యాప్ ఇన్స్టాల్ చేసి ఉందని"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• యాప్ సెటప్ చేయబడి ఉందని"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• కనీసం ఒక పరికరమైనా అందుబాటులో ఉందని"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"రద్దు చేయండి"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ఇప్పుడే తిప్పండి"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"మెరుగైన సెల్ఫీ కోసం ఫోన్ను అన్ఫోల్డ్ చేయండి"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"మంచి సెల్ఫీ కోసం ముందు వైపు డిస్ప్లేకు తిప్పాలా?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"అధిక రిజల్యూషన్తో పెద్ద ఫోటో కోసం వెనుక వైపున ఉన్న కెమెరాను ఉపయోగించండి."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ఈ స్క్రీన్ ఆఫ్ అవుతుంది"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"మడవగల పరికరం విప్పబడుతోంది"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"మడవగల పరికరం చుట్టూ తిప్పబడుతోంది"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 40b997d..736bd68 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ปิดอยู่"</string>
<string name="bt_is_off" msgid="7436344904889461591">"บลูทูธปิดอยู่"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"\"ห้ามรบกวน\" ปิดอยู่"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติ (<xliff:g id="ID_1">%s</xliff:g>)"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"มีการเปิด \"ห้ามรบกวน\" โดยแอป (<xliff:g id="ID_1">%s</xliff:g>)"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติหรือแอป"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"หยุดแคสต์"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"อุปกรณ์ที่พร้อมใช้งานสำหรับเอาต์พุตเสียง"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ระดับเสียง"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"วิธีการทำงานของการออกอากาศ"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"ประกาศ"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ผู้ที่อยู่ใกล้คุณและมีอุปกรณ์บลูทูธที่รองรับสามารถรับฟังสื่อที่คุณกำลังออกอากาศได้"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"กล้องและไมค์ปิดอยู่"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{การแจ้งเตือน # รายการ}other{การแจ้งเตือน # รายการ}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"การจดบันทึก"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"กำลังออกอากาศ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"หยุดการออกอากาศ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"หากคุณออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g> หรือเปลี่ยนแปลงเอาต์พุต การออกอากาศในปัจจุบันจะหยุดลง"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"เปลี่ยนเอาต์พุต"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ไม่ทราบ"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"HH:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"เปิด <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ติดตั้งแอปกล้อง"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• แอปได้รับการตั้งค่าแล้ว"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• มีอุปกรณ์พร้อมใช้งานอย่างน้อย 1 รายการ"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ยกเลิก"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"พลิกเลย"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"กางโทรศัพท์เพื่อเซลฟีที่ดียิ่งขึ้น"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"พลิกเป็นหน้าจอด้านหน้าเพื่อภาพเซลฟีที่ดีขึ้นไหม"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ใช้กล้องหลังเพื่อถ่ายภาพกว้างขึ้นด้วยความละเอียดสูงขึ้น"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ หน้าจอนี้จะปิดไป"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"อุปกรณ์ที่พับได้กำลังกางออก"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"อุปกรณ์ที่พับได้กำลังพลิกไปมา"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index a0b4e29a..51e42dd 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Naka-off ang Wi-Fi"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Naka-off ang Bluetooth"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Naka-off ang Huwag Istorbohin"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Na-on ang Huwag Istorbohin dahil sa isang app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan o app."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ihinto ang pag-cast"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Mga available na device para sa audio output."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Paano gumagana ang pag-broadcast"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Makakapakinig ang mga taong malapit sa iyo na may mga compatible na Bluetooth device sa media na bino-broadcast mo"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Naka-off ang camera at mikropono"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# na notification}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Pagtatala"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Nagbo-broadcast"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ihinto ang pag-broadcast ng <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kung magbo-broadcast ka ng <xliff:g id="SWITCHAPP">%1$s</xliff:g> o babaguhin mo ang output, hihinto ang iyong kasalukuyang broadcast"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"I-broadcast ang <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Baguhin ang output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Hindi alam"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buksan ang <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Mag-install ng camera app"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Na-set up ang app"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• May kahit isang device na available"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselahin"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"I-flip na ngayon"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"I-unfold ang telepono para sa mas magandang selfie"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"I-flip sa front display para sa magandang selfie?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gamitin ang camera sa harap para sa mas malawak na larawan na may mas mataas na resolution."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Mag-o-off ang screen na ito"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ina-unfold na foldable na device"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Fini-flip na foldable na device"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 4fb45b1..bb718ff 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Kablosuz bağlantı kapalı"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth kapalı"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Rahatsız Etmeyin kapalı"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Rahatsız Etmeyin ayarı bir otomatik kural (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Rahatsız Etmeyin ayarı bir uygulama (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Rahatsız Etmeyin ayarı bir otomatik kural veya uygulama tarafından açıldı."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayını durdur"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Ses çıkışı için kullanılabilir cihazlar."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Ses düzeyi"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayınlamanın işleyiş şekli"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Anons"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Yakınınızda ve uyumlu Bluetooth cihazları olan kişiler yayınladığınız medya içeriğini dinleyebilir"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ve mikrofon kapalı"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildirim}other{# bildirim}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Not alma"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayınlama"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında anons durdurulsun mu?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapar veya çıkışı değiştirirseniz mevcut anonsunuz duraklatılır"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapın"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Çıkışı değiştirme"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Bilinmiyor"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM, EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dd"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasını aç"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera uygulaması yüklenmelidir"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Uygulama kurulmuş olmalıdır"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• En az bir cihaz mevcut olmalıdır"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"İptal"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Şimdi çevirin"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha iyi selfie çekmek için telefonu açın"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Daha iyi bir selfie için ön ekrana geçilsin mi?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Daha yüksek çözünürlüğe sahip daha büyük bir fotoğraf için arka yüz kamerasını kullanın."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ * Bu ekran kapatılacak"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Katlanabilir cihaz açılıyor"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Katlanabilir cihaz döndürülüyor"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 5992b01..4e30515 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi вимкнено"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth вимкнено"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не турбувати\" вимкнено"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автоматичне правило ввімкнуло режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Додаток увімкнув режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автоматичне правило або додаток увімкнули режим \"Не турбувати\"."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Припинити трансляцію"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Доступні пристрої для відтворення звуку."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Гучність"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як працює трансляція"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Трансляція"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Люди поблизу, які мають сумісні пристрої з Bluetooth, можуть слухати медіаконтент, який ви транслюєте."</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камеру й мікрофон вимкнено"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# сповіщення}one{# сповіщення}few{# сповіщення}many{# сповіщень}other{# сповіщення}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Створення нотаток"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляція"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Зупинити трансляцію з додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Якщо ви зміните додаток (<xliff:g id="SWITCHAPP">%1$s</xliff:g>) або аудіовихід, поточну трансляцію буде припинено"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Змінити додаток для трансляції на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змінити аудіовихід"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невідомо"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Відкрити <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Встановлено додаток для камери"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Додаток налаштовано"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Принаймні один пристрій доступний"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасувати"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернути"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Розгорніть телефон, щоб зробити краще селфі"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Перемкнути на фронтальну камеру для кращого селфі?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Використовуйте камеру на задній панелі, щоб зробити знімок із ширшим кутом і вищою роздільною здатністю."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Цей екран вимкнеться"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Розкладний пристрій у розкладеному стані"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Розкладний пристрій обертається"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 1a0ce6f..8b249ca 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi آف ہے"</string>
<string name="bt_is_off" msgid="7436344904889461591">"بلوٹوتھ آف ہے"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"\'ڈسٹرب نہ کریں\' آف ہے"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعہ آن ہو گیا تھا۔"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\'ڈسٹرب نہ کریں\' کسی ایپ (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعہ آن ہو گیا تھا۔"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول یا ایپ کے ذریعے آن ہو گیا تھا۔"</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> پر براڈکاسٹ کریں"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"آؤٹ پٹ تبدیل کریں"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامعلوم"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> کھولیں"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• کیمرا ایپ انسٹال کریں"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ایپ سیٹ اپ ہو گئی ہے"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• کم از کم ایک آلہ دستیاب ہے"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"منسوخ کریں"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"اب پلٹائیں"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"بہتر سیلفی کے لیے فون کھولیں"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"بہتر سیلفی کے لیے سامنے والے ڈسپلے پر پلٹائیں؟"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"اعلی ریزولیوشن والی وسیع تصویر کے لیے ییچھے والا کیمرا استعمال کریں۔"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ یہ اسکرین آف ہو جائے گی"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"فولڈ ہونے والے آلے کو کھولا جا رہا ہے"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"فولڈ ہونے والے آلے کو گھمایا جا رہا ہے"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 257edd4..74f29e5 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi o‘chiq"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth o‘chiq"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Bezovta qilinmasin rejimi o‘chiq"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Bezovta qilinmasin rejimi avtomatik qoida (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Bezovta qilinmasin rejimi ilova (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Bezovta qilinmasin rejimi ilova yoki avtomatik qoida tomonidan yoqilgan."</string>
@@ -993,7 +995,6 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ovoz chiqishini oʻzgartirish"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Noaniq"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ochish: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1003,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera ilovasini oʻrnating"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Ilova sozlangan"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Kamida bitta qurilma mavjud"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Bekor qilish"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Hozir aylantirish"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Yaxshiroq selfi olish uchun telefonni yoying"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Old ekran sizga qaragan holda aylantirdingizmi?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Keng va yuqori tiniqlikdagi suratga olish uchun orqa kameradan foydalaning."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran oʻchiriladi"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Buklanadigan qurilma ochilmoqda"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Buklanadigan qurilma aylantirilmoqda"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 53efd2d..94c814c 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi đang tắt"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth tắt"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Không làm phiền tắt"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Không làm phiền đã được một quy tắc tự động (<xliff:g id="ID_1">%s</xliff:g>) bật."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Không làm phiền đã được một ứng dụng (<xliff:g id="ID_1">%s</xliff:g>) bật."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Không làm phiền đã được một quy tắc tự động hoặc ứng dụng bật."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dừng truyền"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Các thiết bị có sẵn để xuất âm thanh."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Âm lượng"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cách tính năng truyền hoạt động"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Truyền"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Những người ở gần có thiết bị Bluetooth tương thích có thể nghe nội dung nghe nhìn bạn đang truyền"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Máy ảnh và micrô đang tắt"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# thông báo}other{# thông báo}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Ghi chú"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Phát sóng"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Dừng phát <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nếu bạn phát <xliff:g id="SWITCHAPP">%1$s</xliff:g> hoặc thay đổi đầu ra, phiên truyền phát hiện tại sẽ dừng"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Phát <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Thay đổi đầu ra"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Không xác định"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Mở <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Cài đặt một ứng dụng máy ảnh"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Ứng dụng được thiết lập"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Có ít nhất một thiết bị đang hoạt động"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Huỷ"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Lật ngay"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Mở điện thoại ra để tự chụp ảnh chân dung đẹp hơn"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Lật sang màn hình ngoài để tự chụp ảnh chân dung đẹp hơn?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Sử dụng máy ảnh sau để chụp ảnh góc rộng hơn với độ phân giải cao hơn."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Màn hình này sẽ tắt"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Thiết bị có thể gập lại đang được mở ra"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Thiết bị có thể gập lại đang được lật ngược"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index c339e8d..082cfb4 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"WLAN 已关闭"</string>
<string name="bt_is_off" msgid="7436344904889461591">"蓝牙已关闭"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"“勿扰”模式已关闭"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"某个自动规则(<xliff:g id="ID_1">%s</xliff:g>)已开启勿扰模式。"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"某个应用(<xliff:g id="ID_1">%s</xliff:g>)已开启勿扰模式。"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某个自动规则或应用已开启勿扰模式。"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"音频输出的可用设备。"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"音量"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"广播的运作方式"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"广播"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近使用兼容蓝牙设备的用户可以收听您广播的媒体内容"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"摄像头和麦克风已关闭"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 条通知}other{# 条通知}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>,<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"记录"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"正在广播"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止广播“<xliff:g id="APP_NAME">%1$s</xliff:g>”的内容吗?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容或更改输出来源,当前的广播就会停止"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"更改输出来源"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"未知"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"打开<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• 安装相机应用"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• 应用已设置完毕"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少有一台设备可用"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻转"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"展开手机可拍出更好的自拍照"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"要翻转到外屏以拍出更好的自拍照吗?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"您可以使用后置摄像头拍摄视角更广、分辨率更高的照片。"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 此屏幕将会关闭"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展开可折叠设备"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻转可折叠设备"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 6ed2835..092fe34 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi 已關閉"</string>
<string name="bt_is_off" msgid="7436344904889461591">"藍牙已關閉"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"「請勿騷擾」已關閉"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已開啟「請勿騷擾」功能。"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已開啟「請勿騷擾」功能。"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某個自動規則或應用程式已開啟「請勿騷擾」功能。"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"可用作音訊輸出的裝置"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"音量"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播運作方式"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近有兼容藍牙裝置的人可收聽您正在廣播的媒體內容"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"相機和麥克風已關閉"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>,<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"做筆記"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止廣播「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如要廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止廣播目前的內容"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• 安裝相機應用程式"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• 應用程式已完成設定"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少一部裝置可用"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻轉"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"打開手機,即可拍攝更出色的自拍"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"要翻轉至前方螢幕拍攝更出色的自拍嗎?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"使用後置鏡頭,拍攝更廣角、解像度更高的相片。"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 此螢幕將關閉"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index b1698d5..e098882 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi 已關閉"</string>
<string name="bt_is_off" msgid="7436344904889461591">"藍牙已關閉"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"零打擾模式已關閉"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已將零打擾模式開啟。"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已將零打擾模式開啟。"</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某個自動規則或應用程式已將零打擾模式開啟。"</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"可用於輸出音訊的裝置。"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"音量"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播功能的運作方式"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"如果附近的人有相容的藍牙裝置,就可以聽到你正在廣播的媒體內容"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"已關閉相機和麥克風"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>,<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"做筆記"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止播送「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止播送目前的內容"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• 安裝相機應用程式"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• 完成應用程式設定"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少要有一部可用裝置"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻轉"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"打開手機自拍效果較佳"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"要翻轉到前螢幕拍攝更優質的自拍照嗎?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"使用後置鏡頭可拍攝視角較寬廣、解析度較高的相片。"</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 這麼做會關閉這個螢幕"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 38a6136..0a2aa8b 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -731,6 +731,8 @@
<string name="wifi_is_off" msgid="5389597396308001471">"I-Wi-Fi ivaliwe"</string>
<string name="bt_is_off" msgid="7436344904889461591">"I-Bluetooth ivaliwe"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Ungaphazamisi kuvaliwe"</string>
+ <!-- no translation found for dnd_is_on (7009368176361546279) -->
+ <skip />
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Okuthi ungaphazamisi kuvulwe umthetho ozenzakalelayo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Okuthi ungaphazamisi kuvulwe uhlelo lokusebenza (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Okuthi ungaphazamisi kuvulwe umthetho ozenzakalelayo noma uhlelo lokusebenza."</string>
@@ -872,8 +874,7 @@
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Misa ukusakaza"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Amadivayisi atholakalayo okukhipha umsindo."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Ivolumu"</string>
- <!-- no translation found for media_output_dialog_volume_percentage (1613984910585111798) -->
- <skip />
+ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Indlela ukusakaza okusebenza ngayo"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Sakaza"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Abantu abaseduze nawe abanamadivayisi e-Bluetooth ahambisanayo bangalalela imidiya oyisakazayo"</string>
@@ -987,15 +988,13 @@
<string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Ikhamera nemakrofoni kuvaliwe"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Isaziso esingu-#}one{Izaziso ezingu-#}other{Izaziso ezingu-#}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <!-- no translation found for note_task_button_label (8718616095800343136) -->
- <skip />
+ <string name="note_task_button_label" msgid="8718616095800343136">"Ukuthatha amanothi"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Ukusakaza"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Misa ukusakaza i-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Uma usakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g> noma ushintsha okuphumayo, ukusakaza kwakho kwamanje kuzoma"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Shintsha okuphumayo"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Akwaziwa"</string>
- <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Vula i-<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1005,14 +1004,16 @@
<string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Faka i-app yekhamera"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• I-app isethiwe"</string>
<string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Okungenani idivayisi eyodwa iyatholakala"</string>
+ <!-- no translation found for keyguard_affordance_press_too_short (2687995216454987952) -->
+ <skip />
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Khansela"</string>
<string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Phendula manje"</string>
<string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vula ifoni ukuze ube nesithombe ozishuthe sona esingcono"</string>
<string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Phendulela kwisibonisi sangaphambili ukuba nesithombe ozishuthe sona esingcono?"</string>
<string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Sebenzisa ikhamera ebheke ngemuva ukuze uthole isithombe esibanzi esinokucaca okuphezulu."</string>
<string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Lesi sikrini sizovala"</b></string>
- <!-- no translation found for rear_display_accessibility_folded_animation (1538121649587978179) -->
- <skip />
- <!-- no translation found for rear_display_accessibility_unfolded_animation (1946153682258289040) -->
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Idivayisi egoqekayo iyembulwa"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Idivayisi egoqekayo iphendulwa nxazonke"</string>
+ <!-- no translation found for stylus_battery_low (7134370101603167096) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 4cda8c7..f0cc42e 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -743,27 +743,6 @@
<!-- How long in milliseconds before full burn-in protection is achieved. -->
<integer name="config_dreamOverlayMillisUntilFullJitter">240000</integer>
- <!-- The duration in milliseconds of the y-translation animation when waking up from
- the dream -->
- <integer name="config_dreamOverlayOutTranslationYDurationMs">333</integer>
- <!-- The delay in milliseconds of the y-translation animation when waking up from
- the dream for the complications at the bottom of the screen -->
- <integer name="config_dreamOverlayOutTranslationYDelayBottomMs">33</integer>
- <!-- The delay in milliseconds of the y-translation animation when waking up from
- the dream for the complications at the top of the screen -->
- <integer name="config_dreamOverlayOutTranslationYDelayTopMs">117</integer>
- <!-- The duration in milliseconds of the alpha animation when waking up from the dream -->
- <integer name="config_dreamOverlayOutAlphaDurationMs">200</integer>
- <!-- The delay in milliseconds of the alpha animation when waking up from the dream for the
- complications at the top of the screen -->
- <integer name="config_dreamOverlayOutAlphaDelayTopMs">217</integer>
- <!-- The delay in milliseconds of the alpha animation when waking up from the dream for the
- complications at the bottom of the screen -->
- <integer name="config_dreamOverlayOutAlphaDelayBottomMs">133</integer>
- <!-- The duration in milliseconds of the blur animation when waking up from
- the dream -->
- <integer name="config_dreamOverlayOutBlurDurationMs">250</integer>
-
<integer name="complicationFadeOutMs">500</integer>
<integer name="complicationFadeInMs">500</integer>
@@ -773,15 +752,15 @@
<integer name="complicationFadeOutDelayMs">200</integer>
<!-- Duration in milliseconds of the dream in un-blur animation. -->
- <integer name="config_dreamOverlayInBlurDurationMs">249</integer>
- <!-- Delay in milliseconds of the dream in un-blur animation. -->
- <integer name="config_dreamOverlayInBlurDelayMs">133</integer>
+ <integer name="config_dreamOverlayInBlurDurationMs">250</integer>
<!-- Duration in milliseconds of the dream in complications fade-in animation. -->
- <integer name="config_dreamOverlayInComplicationsDurationMs">282</integer>
- <!-- Delay in milliseconds of the dream in top complications fade-in animation. -->
- <integer name="config_dreamOverlayInTopComplicationsDelayMs">216</integer>
- <!-- Delay in milliseconds of the dream in bottom complications fade-in animation. -->
- <integer name="config_dreamOverlayInBottomComplicationsDelayMs">299</integer>
+ <integer name="config_dreamOverlayInComplicationsDurationMs">250</integer>
+ <!-- Duration in milliseconds of the y-translation animation when entering a dream -->
+ <integer name="config_dreamOverlayInTranslationYDurationMs">917</integer>
+
+ <!-- Delay in milliseconds before switching to the dock user and dreaming if a secondary user is
+ active when the device is locked and docked. 0 indicates disabled. Default is 1 minute. -->
+ <integer name="config_defaultDockUserTimeoutMs">60000</integer>
<!-- Icons that don't show in a collapsed non-keyguard statusbar -->
<string-array name="config_collapsed_statusbar_icon_blocklist" translatable="false">
@@ -824,6 +803,8 @@
slot. If the user did make a choice, even if the choice is the "None" option, the default is
ignored. -->
<string-array name="config_keyguardQuickAffordanceDefaults" translatable="false">
+ <item>bottom_start:home</item>
+ <item>bottom_end:wallet</item>
</string-array>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c10e7528..87d2c51 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -218,6 +218,9 @@
<!-- Radius for notifications corners with adjacent notifications -->
<dimen name="notification_corner_radius_small">4dp</dimen>
+ <!-- Vertical padding of the FSI container -->
+ <dimen name="fsi_chrome_vertical_padding">80dp</dimen>
+
<!-- the padding of the shelf icon container -->
<dimen name="shelf_icon_container_padding">13dp</dimen>
@@ -758,6 +761,8 @@
<dimen name="keyguard_affordance_fixed_height">48dp</dimen>
<dimen name="keyguard_affordance_fixed_width">48dp</dimen>
<dimen name="keyguard_affordance_fixed_radius">24dp</dimen>
+ <!-- Amount the button should shake when it's not long-pressed for long enough. -->
+ <dimen name="keyguard_affordance_shake_amplitude">8dp</dimen>
<dimen name="keyguard_affordance_horizontal_offset">32dp</dimen>
<dimen name="keyguard_affordance_vertical_offset">32dp</dimen>
@@ -1505,6 +1510,8 @@
<dimen name="dream_overlay_status_bar_extra_margin">8dp</dimen>
<!-- Dream overlay complications related dimensions -->
+ <!-- The blur radius applied to the dream overlay when entering and exiting dreams -->
+ <dimen name="dream_overlay_anim_blur_radius">50dp</dimen>
<dimen name="dream_overlay_complication_clock_time_text_size">86dp</dimen>
<dimen name="dream_overlay_complication_clock_time_translation_y">28dp</dimen>
<dimen name="dream_overlay_complication_home_controls_padding">28dp</dimen>
@@ -1558,6 +1565,7 @@
<dimen name="dream_overlay_complication_margin">0dp</dimen>
<dimen name="dream_overlay_y_offset">80dp</dimen>
+ <dimen name="dream_overlay_entry_y_offset">40dp</dimen>
<dimen name="dream_overlay_exit_y_offset">40dp</dimen>
<dimen name="status_view_margin_horizontal">0dp</dimen>
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index fd2e324..c5ffc94 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -30,6 +30,9 @@
<bool name="flag_charging_ripple">false</bool>
+ <!-- Whether to show chipbar UI whenever the device is unlocked by ActiveUnlock. -->
+ <bool name="flag_active_unlock_chipbar">true</bool>
+
<bool name="flag_smartspace">false</bool>
<!-- Whether the user switcher chip shows in the status bar. When true, the multi user
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 7ca42f7..b5ac940 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -142,6 +142,9 @@
<item type="id" name="row_tag_for_content_view" />
+ <!-- Chipbar -->
+ <item type="id" name="tag_chipbar_info"/>
+
<!-- Optional cancel button on Keyguard -->
<item type="id" name="cancel_button"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 643f831..7a8ffa1 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -227,6 +227,8 @@
<string name="screenshot_scroll_label">Capture more</string>
<!-- Content description indicating that tapping a button will dismiss the screenshots UI [CHAR LIMIT=NONE] -->
<string name="screenshot_dismiss_description">Dismiss screenshot</string>
+ <!-- Content description indicating that tapping a button will dismiss the work profile first run dialog [CHAR LIMIT=NONE] -->
+ <string name="screenshot_dismiss_work_profile">Dismiss work profile message</string>
<!-- Content description indicating that the view is a preview of the screenshot that was just taken [CHAR LIMIT=NONE] -->
<string name="screenshot_preview_description">Screenshot preview</string>
<!-- Content description for the top boundary of the screenshot being cropped, with the current position as a percentage. [CHAR LIMIT=NONE] -->
@@ -2035,6 +2037,9 @@
<!-- Label for when Do not disturb is off in QS detail panel [CHAR LIMIT=NONE] -->
<string name="dnd_is_off">Do Not Disturb is off</string>
+ <!-- Label for when Do not disturb is on in lockscreen quick affordance [CHAR LIMIT=NONE] -->
+ <string name="dnd_is_on">Do Not Disturb is on</string>
+
<!-- Prompt for when Do not disturb is on from automatic rule in QS [CHAR LIMIT=NONE] -->
<string name="qs_dnd_prompt_auto_rule">Do Not Disturb was turned on by an automatic rule (<xliff:g name="rule">%s</xliff:g>).</string>
@@ -2403,6 +2408,8 @@
<string name="media_output_dialog_accessibility_seekbar">Volume</string>
<!-- Summary for media output volume of a device in percentage [CHAR LIMIT=NONE] -->
<string name="media_output_dialog_volume_percentage"><xliff:g id="percentage" example="10">%1$d</xliff:g>%%</string>
+ <!-- Title for Speakers and Displays group. [CHAR LIMIT=NONE] -->
+ <string name="media_output_group_title_speakers_and_displays">Speakers & Displays</string>
<!-- Media Output Broadcast Dialog -->
<!-- Title for Broadcast First Notify Dialog [CHAR LIMIT=60] -->
@@ -2740,6 +2747,12 @@
-->
<string name="keyguard_affordance_enablement_dialog_home_instruction_2">• At least one device is available</string>
+ <!--
+ Error message shown when a button should be pressed and held to activate it, usually shown when
+ the user attempted to tap the button or held it for too short a time. [CHAR LIMIT=32].
+ -->
+ <string name="keyguard_affordance_press_too_short">Press and hold to activate</string>
+
<!-- Text for education page of cancel button to hide the page. [CHAR_LIMIT=NONE] -->
<string name="rear_display_bottom_sheet_cancel">Cancel</string>
<!-- Text for the user to confirm they flipped the device around. [CHAR_LIMIT=NONE] -->
@@ -2756,4 +2769,7 @@
<string name="rear_display_accessibility_folded_animation">Foldable device being unfolded</string>
<!-- Text for education page content description for unfolded animation. [CHAR_LIMIT=NONE] -->
<string name="rear_display_accessibility_unfolded_animation">Foldable device being flipped around</string>
+
+ <!-- Title for notification of low stylus battery. [CHAR_LIMIT=NONE] -->
+ <string name="stylus_battery_low">Stylus battery low</string>
</resources>
diff --git a/packages/SystemUI/res/xml/media_session_expanded.xml b/packages/SystemUI/res/xml/media_session_expanded.xml
index 64c2ef1..7de0a5e 100644
--- a/packages/SystemUI/res/xml/media_session_expanded.xml
+++ b/packages/SystemUI/res/xml/media_session_expanded.xml
@@ -88,20 +88,18 @@
The chain is set to "spread" so that the progress bar can be weighted to fill any empty space.
-->
<Constraint
- android:id="@+id/media_scrubbing_elapsed_time"
+ android:id="@+id/actionPrev"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toLeftOf="@id/actionPrev"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="spread" />
<Constraint
- android:id="@+id/actionPrev"
+ android:id="@+id/media_scrubbing_elapsed_time"
android:layout_width="48dp"
android:layout_height="48dp"
- app:layout_constraintLeft_toRightOf="@id/media_scrubbing_elapsed_time"
- app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
+ app:layout_constraintLeft_toRightOf="@id/actionPrev"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="spread" />
@@ -109,7 +107,7 @@
android:id="@+id/media_progress_bar"
android:layout_width="0dp"
android:layout_height="48dp"
- app:layout_constraintLeft_toRightOf="@id/actionPrev"
+ app:layout_constraintLeft_toRightOf="@id/media_scrubbing_elapsed_time"
app:layout_constraintRight_toLeftOf="@id/actionNext"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1" />
@@ -118,7 +116,6 @@
android:id="@+id/actionNext"
android:layout_width="48dp"
android:layout_height="48dp"
- app:layout_constraintLeft_toRightOf="@id/media_progress_bar"
app:layout_constraintRight_toLeftOf="@id/media_scrubbing_total_time"
app:layout_constraintBottom_toBottomOf="parent" />
@@ -126,7 +123,6 @@
android:id="@+id/media_scrubbing_total_time"
android:layout_width="48dp"
android:layout_height="48dp"
- app:layout_constraintLeft_toRightOf="@id/actionNext"
app:layout_constraintRight_toLeftOf="@id/action0"
app:layout_constraintBottom_toBottomOf="parent" />
@@ -134,7 +130,6 @@
android:id="@+id/action0"
android:layout_width="48dp"
android:layout_height="48dp"
- app:layout_constraintLeft_toRightOf="@id/media_scrubbing_total_time"
app:layout_constraintRight_toLeftOf="@id/action1"
app:layout_constraintBottom_toBottomOf="parent" />
@@ -142,7 +137,6 @@
android:id="@+id/action1"
android:layout_width="48dp"
android:layout_height="48dp"
- app:layout_constraintLeft_toRightOf="@id/action0"
app:layout_constraintRight_toLeftOf="@id/action2"
app:layout_constraintBottom_toBottomOf="parent" />
@@ -150,7 +144,6 @@
android:id="@+id/action2"
android:layout_width="48dp"
android:layout_height="48dp"
- app:layout_constraintLeft_toRightOf="@id/action1"
app:layout_constraintRight_toLeftOf="@id/action3"
app:layout_constraintBottom_toBottomOf="parent" />
@@ -158,7 +151,6 @@
android:id="@+id/action3"
android:layout_width="48dp"
android:layout_height="48dp"
- app:layout_constraintLeft_toRightOf="@id/action2"
app:layout_constraintRight_toLeftOf="@id/action4"
app:layout_constraintBottom_toBottomOf="parent" />
@@ -166,7 +158,6 @@
android:id="@+id/action4"
android:layout_width="48dp"
android:layout_height="48dp"
- app:layout_constraintLeft_toRightOf="@id/action3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</ConstraintSet>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
index 6087655..8ee893c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
@@ -71,7 +71,7 @@
*/
public class RotationButtonController {
- private static final String TAG = "StatusBar/RotationButtonController";
+ private static final String TAG = "RotationButtonController";
private static final int BUTTON_FADE_IN_OUT_DURATION_MS = 100;
private static final int NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS = 20000;
private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
@@ -377,6 +377,7 @@
}
// Prepare to show the navbar icon by updating the icon style to change anim params
+ Log.i(TAG, "onRotationProposal(rotation=" + rotation + ")");
mLastRotationSuggestion = rotation; // Remember rotation for click
final boolean rotationCCW = Utilities.isRotationAnimationCCW(windowRotation, rotation);
if (windowRotation == Surface.ROTATION_0 || windowRotation == Surface.ROTATION_180) {
@@ -499,6 +500,7 @@
mUiEventLogger.log(RotationButtonEvent.ROTATION_SUGGESTION_ACCEPTED);
incrementNumAcceptedRotationSuggestionsIfNeeded();
setRotationLockedAtAngle(mLastRotationSuggestion);
+ Log.i(TAG, "onRotateSuggestionClick() mLastRotationSuggestion=" + mLastRotationSuggestion);
v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardActiveUnlockModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardActiveUnlockModel.kt
new file mode 100644
index 0000000..3a89c13
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardActiveUnlockModel.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.annotation.CurrentTimeMillisLong
+import com.android.systemui.dump.DumpsysTableLogger
+import com.android.systemui.dump.Row
+import com.android.systemui.plugins.util.RingBuffer
+
+/** Verbose debug information. */
+data class KeyguardActiveUnlockModel(
+ @CurrentTimeMillisLong override var timeMillis: Long = 0L,
+ override var userId: Int = 0,
+ override var listening: Boolean = false,
+ // keep sorted
+ var awakeKeyguard: Boolean = false,
+ var authInterruptActive: Boolean = false,
+ var fpLockedOut: Boolean = false,
+ var primaryAuthRequired: Boolean = false,
+ var switchingUser: Boolean = false,
+ var triggerActiveUnlockForAssistant: Boolean = false,
+ var userCanDismissLockScreen: Boolean = false,
+) : KeyguardListenModel() {
+
+ /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */
+ val asStringList: List<String> by lazy {
+ listOf(
+ DATE_FORMAT.format(timeMillis),
+ timeMillis.toString(),
+ userId.toString(),
+ listening.toString(),
+ // keep sorted
+ awakeKeyguard.toString(),
+ authInterruptActive.toString(),
+ fpLockedOut.toString(),
+ primaryAuthRequired.toString(),
+ switchingUser.toString(),
+ triggerActiveUnlockForAssistant.toString(),
+ userCanDismissLockScreen.toString(),
+ )
+ }
+
+ /**
+ * [RingBuffer] to store [KeyguardActiveUnlockModel]. After the buffer is full, it will recycle
+ * old events.
+ *
+ * Do not use [append] to add new elements. Instead use [insert], as it will recycle if
+ * necessary.
+ */
+ class Buffer {
+ private val buffer = RingBuffer(CAPACITY) { KeyguardActiveUnlockModel() }
+
+ fun insert(model: KeyguardActiveUnlockModel) {
+ buffer.advance().apply {
+ timeMillis = model.timeMillis
+ userId = model.userId
+ listening = model.listening
+ // keep sorted
+ awakeKeyguard = model.awakeKeyguard
+ authInterruptActive = model.authInterruptActive
+ fpLockedOut = model.fpLockedOut
+ primaryAuthRequired = model.primaryAuthRequired
+ switchingUser = model.switchingUser
+ triggerActiveUnlockForAssistant = model.triggerActiveUnlockForAssistant
+ userCanDismissLockScreen = model.userCanDismissLockScreen
+ }
+ }
+
+ /**
+ * Returns the content of the buffer (sorted from latest to newest).
+ *
+ * @see KeyguardFingerprintListenModel.asStringList
+ */
+ fun toList(): List<Row> {
+ return buffer.asSequence().map { it.asStringList }.toList()
+ }
+ }
+
+ companion object {
+ const val CAPACITY = 20 // number of logs to retain
+
+ /** Headers for dumping a table using [DumpsysTableLogger]. */
+ @JvmField
+ val TABLE_HEADERS =
+ listOf(
+ "timestamp",
+ "time_millis",
+ "userId",
+ "listening",
+ // keep sorted
+ "awakeKeyguard",
+ "authInterruptActive",
+ "fpLockedOut",
+ "primaryAuthRequired",
+ "switchingUser",
+ "triggerActiveUnlockForAssistant",
+ "userCanDismissLockScreen",
+ )
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 40423cd..62babad 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -9,6 +9,7 @@
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
@@ -43,6 +44,21 @@
public static final int LARGE = 0;
public static final int SMALL = 1;
+ /** Returns a region for the large clock to position itself, based on the given parent. */
+ public static Rect getLargeClockRegion(ViewGroup parent) {
+ int largeClockTopMargin = parent.getResources()
+ .getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin);
+ int targetHeight = parent.getResources()
+ .getDimensionPixelSize(R.dimen.large_clock_text_size) * 2;
+ int top = parent.getHeight() / 2 - targetHeight / 2
+ + largeClockTopMargin / 2;
+ return new Rect(
+ parent.getLeft(),
+ top,
+ parent.getRight(),
+ top + targetHeight);
+ }
+
/**
* Frame for small/large clocks
*/
@@ -129,17 +145,8 @@
}
if (mLargeClockFrame.isLaidOut()) {
- int largeClockTopMargin = getResources()
- .getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin);
- int targetHeight = getResources()
- .getDimensionPixelSize(R.dimen.large_clock_text_size) * 2;
- int top = mLargeClockFrame.getHeight() / 2 - targetHeight / 2
- + largeClockTopMargin / 2;
- mClock.getLargeClock().getEvents().onTargetRegionChanged(new Rect(
- mLargeClockFrame.getLeft(),
- top,
- mLargeClockFrame.getRight(),
- top + targetHeight));
+ mClock.getLargeClock().getEvents().onTargetRegionChanged(
+ getLargeClockRegion(mLargeClockFrame));
}
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
new file mode 100644
index 0000000..deead19
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.annotation.CurrentTimeMillisLong
+import com.android.systemui.dump.DumpsysTableLogger
+import com.android.systemui.dump.Row
+import com.android.systemui.plugins.util.RingBuffer
+
+/** Verbose debug information associated. */
+data class KeyguardFaceListenModel(
+ @CurrentTimeMillisLong override var timeMillis: Long = 0L,
+ override var userId: Int = 0,
+ override var listening: Boolean = false,
+ // keep sorted
+ var authInterruptActive: Boolean = false,
+ var biometricSettingEnabledForUser: Boolean = false,
+ var bouncerFullyShown: Boolean = false,
+ var faceAndFpNotAuthenticated: Boolean = false,
+ var faceAuthAllowed: Boolean = false,
+ var faceDisabled: Boolean = false,
+ var faceLockedOut: Boolean = false,
+ var goingToSleep: Boolean = false,
+ var keyguardAwake: Boolean = false,
+ var keyguardGoingAway: Boolean = false,
+ var listeningForFaceAssistant: Boolean = false,
+ var occludingAppRequestingFaceAuth: Boolean = false,
+ var primaryUser: Boolean = false,
+ var secureCameraLaunched: Boolean = false,
+ var supportsDetect: Boolean = false,
+ var switchingUser: Boolean = false,
+ var udfpsBouncerShowing: Boolean = false,
+ var udfpsFingerDown: Boolean = false,
+ var userNotTrustedOrDetectionIsNeeded: Boolean = false,
+) : KeyguardListenModel() {
+
+ /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */
+ val asStringList: List<String> by lazy {
+ listOf(
+ DATE_FORMAT.format(timeMillis),
+ timeMillis.toString(),
+ userId.toString(),
+ listening.toString(),
+ // keep sorted
+ authInterruptActive.toString(),
+ biometricSettingEnabledForUser.toString(),
+ bouncerFullyShown.toString(),
+ faceAndFpNotAuthenticated.toString(),
+ faceAuthAllowed.toString(),
+ faceDisabled.toString(),
+ faceLockedOut.toString(),
+ goingToSleep.toString(),
+ keyguardAwake.toString(),
+ keyguardGoingAway.toString(),
+ listeningForFaceAssistant.toString(),
+ occludingAppRequestingFaceAuth.toString(),
+ primaryUser.toString(),
+ secureCameraLaunched.toString(),
+ supportsDetect.toString(),
+ switchingUser.toString(),
+ udfpsBouncerShowing.toString(),
+ udfpsFingerDown.toString(),
+ userNotTrustedOrDetectionIsNeeded.toString(),
+ )
+ }
+
+ /**
+ * [RingBuffer] to store [KeyguardFaceListenModel]. After the buffer is full, it will recycle
+ * old events.
+ *
+ * Do not use [append] to add new elements. Instead use [insert], as it will recycle if
+ * necessary.
+ */
+ class Buffer {
+ private val buffer = RingBuffer(CAPACITY) { KeyguardFaceListenModel() }
+
+ fun insert(model: KeyguardFaceListenModel) {
+ buffer.advance().apply {
+ timeMillis = model.timeMillis
+ userId = model.userId
+ listening = model.listening
+ // keep sorted
+ biometricSettingEnabledForUser = model.biometricSettingEnabledForUser
+ bouncerFullyShown = model.bouncerFullyShown
+ faceAndFpNotAuthenticated = model.faceAndFpNotAuthenticated
+ faceAuthAllowed = model.faceAuthAllowed
+ faceDisabled = model.faceDisabled
+ faceLockedOut = model.faceLockedOut
+ goingToSleep = model.goingToSleep
+ keyguardAwake = model.keyguardAwake
+ goingToSleep = model.goingToSleep
+ keyguardGoingAway = model.keyguardGoingAway
+ listeningForFaceAssistant = model.listeningForFaceAssistant
+ occludingAppRequestingFaceAuth = model.occludingAppRequestingFaceAuth
+ primaryUser = model.primaryUser
+ secureCameraLaunched = model.secureCameraLaunched
+ supportsDetect = model.supportsDetect
+ switchingUser = model.switchingUser
+ udfpsBouncerShowing = model.udfpsBouncerShowing
+ switchingUser = model.switchingUser
+ udfpsFingerDown = model.udfpsFingerDown
+ userNotTrustedOrDetectionIsNeeded = model.userNotTrustedOrDetectionIsNeeded
+ }
+ }
+ /**
+ * Returns the content of the buffer (sorted from latest to newest).
+ *
+ * @see KeyguardFingerprintListenModel.asStringList
+ */
+ fun toList(): List<Row> {
+ return buffer.asSequence().map { it.asStringList }.toList()
+ }
+ }
+
+ companion object {
+ const val CAPACITY = 40 // number of logs to retain
+
+ /** Headers for dumping a table using [DumpsysTableLogger]. */
+ @JvmField
+ val TABLE_HEADERS =
+ listOf(
+ "timestamp",
+ "time_millis",
+ "userId",
+ "listening",
+ // keep sorted
+ "authInterruptActive",
+ "biometricSettingEnabledForUser",
+ "bouncerFullyShown",
+ "faceAndFpNotAuthenticated",
+ "faceAuthAllowed",
+ "faceDisabled",
+ "faceLockedOut",
+ "goingToSleep",
+ "keyguardAwake",
+ "keyguardGoingAway",
+ "listeningForFaceAssistant",
+ "occludingAppRequestingFaceAuth",
+ "primaryUser",
+ "secureCameraLaunched",
+ "supportsDetect",
+ "switchingUser",
+ "udfpsBouncerShowing",
+ "udfpsFingerDown",
+ "userNotTrustedOrDetectionIsNeeded",
+ )
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
new file mode 100644
index 0000000..998dc09
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.annotation.CurrentTimeMillisLong
+import com.android.systemui.dump.DumpsysTableLogger
+import com.android.systemui.dump.Row
+import com.android.systemui.plugins.util.RingBuffer
+
+/** Verbose debug information. */
+data class KeyguardFingerprintListenModel(
+ @CurrentTimeMillisLong override var timeMillis: Long = 0L,
+ override var userId: Int = 0,
+ override var listening: Boolean = false,
+ // keepSorted
+ var biometricEnabledForUser: Boolean = false,
+ var bouncerIsOrWillShow: Boolean = false,
+ var canSkipBouncer: Boolean = false,
+ var credentialAttempted: Boolean = false,
+ var deviceInteractive: Boolean = false,
+ var dreaming: Boolean = false,
+ var fingerprintDisabled: Boolean = false,
+ var fingerprintLockedOut: Boolean = false,
+ var goingToSleep: Boolean = false,
+ var keyguardGoingAway: Boolean = false,
+ var keyguardIsVisible: Boolean = false,
+ var keyguardOccluded: Boolean = false,
+ var occludingAppRequestingFp: Boolean = false,
+ var primaryUser: Boolean = false,
+ var shouldListenSfpsState: Boolean = false,
+ var shouldListenForFingerprintAssistant: Boolean = false,
+ var strongerAuthRequired: Boolean = false,
+ var switchingUser: Boolean = false,
+ var udfps: Boolean = false,
+ var userDoesNotHaveTrust: Boolean = false,
+) : KeyguardListenModel() {
+
+ /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */
+ val asStringList: List<String> by lazy {
+ listOf(
+ DATE_FORMAT.format(timeMillis),
+ timeMillis.toString(),
+ userId.toString(),
+ listening.toString(),
+ // keep sorted
+ biometricEnabledForUser.toString(),
+ bouncerIsOrWillShow.toString(),
+ canSkipBouncer.toString(),
+ credentialAttempted.toString(),
+ deviceInteractive.toString(),
+ dreaming.toString(),
+ fingerprintDisabled.toString(),
+ fingerprintLockedOut.toString(),
+ goingToSleep.toString(),
+ keyguardGoingAway.toString(),
+ keyguardIsVisible.toString(),
+ keyguardOccluded.toString(),
+ occludingAppRequestingFp.toString(),
+ primaryUser.toString(),
+ shouldListenSfpsState.toString(),
+ shouldListenForFingerprintAssistant.toString(),
+ strongerAuthRequired.toString(),
+ switchingUser.toString(),
+ udfps.toString(),
+ userDoesNotHaveTrust.toString(),
+ )
+ }
+
+ /**
+ * [RingBuffer] to store [KeyguardFingerprintListenModel]. After the buffer is full, it will
+ * recycle old events.
+ *
+ * Do not use [append] to add new elements. Instead use [insert], as it will recycle if
+ * necessary.
+ */
+ class Buffer {
+ private val buffer = RingBuffer(CAPACITY) { KeyguardFingerprintListenModel() }
+
+ fun insert(model: KeyguardFingerprintListenModel) {
+ buffer.advance().apply {
+ timeMillis = model.timeMillis
+ userId = model.userId
+ listening = model.listening
+ // keep sorted
+ biometricEnabledForUser = model.biometricEnabledForUser
+ bouncerIsOrWillShow = model.bouncerIsOrWillShow
+ canSkipBouncer = model.canSkipBouncer
+ credentialAttempted = model.credentialAttempted
+ deviceInteractive = model.deviceInteractive
+ dreaming = model.dreaming
+ fingerprintDisabled = model.fingerprintDisabled
+ fingerprintLockedOut = model.fingerprintLockedOut
+ goingToSleep = model.goingToSleep
+ keyguardGoingAway = model.keyguardGoingAway
+ keyguardIsVisible = model.keyguardIsVisible
+ keyguardOccluded = model.keyguardOccluded
+ occludingAppRequestingFp = model.occludingAppRequestingFp
+ primaryUser = model.primaryUser
+ shouldListenSfpsState = model.shouldListenSfpsState
+ shouldListenForFingerprintAssistant = model.shouldListenForFingerprintAssistant
+ strongerAuthRequired = model.strongerAuthRequired
+ switchingUser = model.switchingUser
+ udfps = model.udfps
+ userDoesNotHaveTrust = model.userDoesNotHaveTrust
+ }
+ }
+
+ /**
+ * Returns the content of the buffer (sorted from latest to newest).
+ *
+ * @see KeyguardFingerprintListenModel.asStringList
+ */
+ fun toList(): List<Row> {
+ return buffer.asSequence().map { it.asStringList }.toList()
+ }
+ }
+
+ companion object {
+ const val CAPACITY = 20 // number of logs to retain
+
+ /** Headers for dumping a table using [DumpsysTableLogger]. */
+ @JvmField
+ val TABLE_HEADERS =
+ listOf(
+ "timestamp",
+ "time_millis",
+ "userId",
+ "listening",
+ // keep sorted
+ "biometricAllowedForUser",
+ "bouncerIsOrWillShow",
+ "canSkipBouncer",
+ "credentialAttempted",
+ "deviceInteractive",
+ "dreaming",
+ "fingerprintDisabled",
+ "fingerprintLockedOut",
+ "goingToSleep",
+ "keyguardGoingAway",
+ "keyguardIsVisible",
+ "keyguardOccluded",
+ "occludingAppRequestingFp",
+ "primaryUser",
+ "shouldListenSidFingerprintState",
+ "shouldListenForFingerprintAssistant",
+ "strongAuthRequired",
+ "switchingUser",
+ "underDisplayFingerprint",
+ "userDoesNotHaveTrust",
+ )
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
index 2b660de..d4ca8e3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
@@ -67,8 +67,12 @@
private final KeyguardUpdateMonitorCallback mUpdateCallback =
new KeyguardUpdateMonitorCallback() {
@Override
- public void onTrustGrantedForCurrentUser(boolean dismissKeyguard,
- TrustGrantFlags flags, String message) {
+ public void onTrustGrantedForCurrentUser(
+ boolean dismissKeyguard,
+ boolean newlyUnlocked,
+ TrustGrantFlags flags,
+ String message
+ ) {
if (dismissKeyguard) {
if (!mView.isVisibleToUser()) {
// The trust agent dismissed the keyguard without the user proving
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
index 52ca166..1296cf3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
@@ -1,87 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.keyguard
-import android.annotation.CurrentTimeMillisLong
+import java.text.SimpleDateFormat
+import java.util.Locale
/** Verbose logging for various keyguard listening states. */
sealed class KeyguardListenModel {
/** Timestamp of the state change. */
- abstract val timeMillis: Long
+ abstract var timeMillis: Long
/** Current user. */
- abstract val userId: Int
+ abstract var userId: Int
/** If keyguard is listening for the modality represented by this model. */
- abstract val listening: Boolean
+ abstract var listening: Boolean
}
-/**
- * Verbose debug information associated with [KeyguardUpdateMonitor.shouldListenForFingerprint].
- */
-data class KeyguardFingerprintListenModel(
- @CurrentTimeMillisLong override val timeMillis: Long,
- override val userId: Int,
- override val listening: Boolean,
- // keep sorted
- val biometricEnabledForUser: Boolean,
- val bouncerIsOrWillShow: Boolean,
- val canSkipBouncer: Boolean,
- val credentialAttempted: Boolean,
- val deviceInteractive: Boolean,
- val dreaming: Boolean,
- val fingerprintDisabled: Boolean,
- val fingerprintLockedOut: Boolean,
- val goingToSleep: Boolean,
- val keyguardGoingAway: Boolean,
- val keyguardIsVisible: Boolean,
- val keyguardOccluded: Boolean,
- val occludingAppRequestingFp: Boolean,
- val primaryUser: Boolean,
- val shouldListenSfpsState: Boolean,
- val shouldListenForFingerprintAssistant: Boolean,
- val strongerAuthRequired: Boolean,
- val switchingUser: Boolean,
- val udfps: Boolean,
- val userDoesNotHaveTrust: Boolean
-) : KeyguardListenModel()
-/**
- * Verbose debug information associated with [KeyguardUpdateMonitor.shouldListenForFace].
- */
-data class KeyguardFaceListenModel(
- @CurrentTimeMillisLong override val timeMillis: Long,
- override val userId: Int,
- override val listening: Boolean,
- // keep sorted
- val authInterruptActive: Boolean,
- val biometricSettingEnabledForUser: Boolean,
- val bouncerFullyShown: Boolean,
- val faceAndFpNotAuthenticated: Boolean,
- val faceAuthAllowed: Boolean,
- val faceDisabled: Boolean,
- val faceLockedOut: Boolean,
- val goingToSleep: Boolean,
- val keyguardAwake: Boolean,
- val keyguardGoingAway: Boolean,
- val listeningForFaceAssistant: Boolean,
- val occludingAppRequestingFaceAuth: Boolean,
- val primaryUser: Boolean,
- val secureCameraLaunched: Boolean,
- val supportsDetect: Boolean,
- val switchingUser: Boolean,
- val udfpsBouncerShowing: Boolean,
- val udfpsFingerDown: Boolean,
- val userNotTrustedOrDetectionIsNeeded: Boolean,
- ) : KeyguardListenModel()
-/**
- * Verbose debug information associated with [KeyguardUpdateMonitor.shouldTriggerActiveUnlock].
- */
-data class KeyguardActiveUnlockModel(
- @CurrentTimeMillisLong override val timeMillis: Long,
- override val userId: Int,
- override val listening: Boolean,
- // keep sorted
- val awakeKeyguard: Boolean,
- val authInterruptActive: Boolean,
- val fpLockedOut: Boolean,
- val primaryAuthRequired: Boolean,
- val switchingUser: Boolean,
- val triggerActiveUnlockForAssistant: Boolean,
- val userCanDismissLockScreen: Boolean
-) : KeyguardListenModel()
+val DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardListenQueue.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardListenQueue.kt
deleted file mode 100644
index 210f5e7..0000000
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardListenQueue.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.keyguard
-
-import androidx.annotation.VisibleForTesting
-import java.io.PrintWriter
-import java.text.DateFormat
-import java.text.SimpleDateFormat
-import java.util.Date
-import java.util.Locale
-import kotlin.collections.ArrayDeque
-
-private val DEFAULT_FORMATTING = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US)
-
-/** Queue for verbose logging checks for the listening state. */
-class KeyguardListenQueue(
- val sizePerModality: Int = 20
-) {
- private val faceQueue = ArrayDeque<KeyguardFaceListenModel>()
- private val fingerprintQueue = ArrayDeque<KeyguardFingerprintListenModel>()
- private val activeUnlockQueue = ArrayDeque<KeyguardActiveUnlockModel>()
-
- @get:VisibleForTesting val models: List<KeyguardListenModel>
- get() = faceQueue + fingerprintQueue + activeUnlockQueue
-
- /** Push a [model] to the queue (will be logged until the queue exceeds [sizePerModality]). */
- fun add(model: KeyguardListenModel) {
- val queue = when (model) {
- is KeyguardFaceListenModel -> faceQueue.apply { add(model) }
- is KeyguardFingerprintListenModel -> fingerprintQueue.apply { add(model) }
- is KeyguardActiveUnlockModel -> activeUnlockQueue.apply { add(model) }
- }
-
- if (queue.size > sizePerModality) {
- queue.removeFirstOrNull()
- }
- }
-
- /** Print verbose logs via the [writer]. */
- @JvmOverloads
- fun print(writer: PrintWriter, dateFormat: DateFormat = DEFAULT_FORMATTING) {
- val stringify: (KeyguardListenModel) -> String = { model ->
- " ${dateFormat.format(Date(model.timeMillis))} $model"
- }
-
- writer.println(" Face listen results (last ${faceQueue.size} calls):")
- for (model in faceQueue) {
- writer.println(stringify(model))
- }
- writer.println(" Fingerprint listen results (last ${fingerprintQueue.size} calls):")
- for (model in fingerprintQueue) {
- writer.println(stringify(model))
- }
- writer.println(" Active unlock triggers (last ${activeUnlockQueue.size} calls):")
- for (model in activeUnlockQueue) {
- writer.println(stringify(model))
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 67e3400..061ca4f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -177,8 +177,6 @@
@Override
public void startAppearAnimation() {
- setAlpha(1f);
- setTranslationY(0);
if (mAppearAnimator.isRunning()) {
mAppearAnimator.cancel();
}
@@ -215,6 +213,7 @@
/** Animate subviews according to expansion or time. */
private void animate(float progress) {
+ setAlpha(progress);
Interpolator standardDecelerate = Interpolators.STANDARD_DECELERATE;
Interpolator legacyDecelerate = Interpolators.LEGACY_DECELERATE;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index c985fd7..c1fae9e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -24,6 +24,7 @@
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
+import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
import android.animation.Animator;
@@ -107,6 +108,8 @@
return R.string.kg_prompt_reason_timeout_password;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
return R.string.kg_prompt_reason_timeout_password;
+ case PROMPT_REASON_TRUSTAGENT_EXPIRED:
+ return R.string.kg_prompt_reason_timeout_password;
case PROMPT_REASON_NONE:
return 0;
default:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 571d274..0c17489 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -313,6 +313,9 @@
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
mMessageAreaController.setMessage(R.string.kg_prompt_reason_timeout_pattern);
break;
+ case PROMPT_REASON_TRUSTAGENT_EXPIRED:
+ mMessageAreaController.setMessage(R.string.kg_prompt_reason_timeout_pattern);
+ break;
case PROMPT_REASON_NONE:
break;
default:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index c46e33d..0a91150 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -22,6 +22,7 @@
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
+import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
import android.animation.Animator;
@@ -123,6 +124,8 @@
return R.string.kg_prompt_reason_timeout_pin;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
return R.string.kg_prompt_reason_timeout_pin;
+ case PROMPT_REASON_TRUSTAGENT_EXPIRED:
+ return R.string.kg_prompt_reason_timeout_pin;
case PROMPT_REASON_NONE:
return 0;
default:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
index ac00e94..67d77e5 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
@@ -61,6 +61,12 @@
int PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT = 7;
/**
+ * Some auth is required because the trustagent expired either from timeout or manually by the
+ * user
+ */
+ int PROMPT_REASON_TRUSTAGENT_EXPIRED = 8;
+
+ /**
* Reset the view and prepare to take input. This should do things like clearing the
* password or pattern and clear error messages.
*/
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index ec4b780..2c3d3a0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -146,6 +146,7 @@
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.dump.DumpsysTableLogger;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.settings.UserTracker;
@@ -461,14 +462,18 @@
private final SparseBooleanArray mBiometricEnabledForUser = new SparseBooleanArray();
private final Map<Integer, Intent> mSecondaryLockscreenRequirement = new HashMap<>();
+ private final KeyguardFingerprintListenModel.Buffer mFingerprintListenBuffer =
+ new KeyguardFingerprintListenModel.Buffer();
+ private final KeyguardFaceListenModel.Buffer mFaceListenBuffer =
+ new KeyguardFaceListenModel.Buffer();
+ private final KeyguardActiveUnlockModel.Buffer mActiveUnlockTriggerBuffer =
+ new KeyguardActiveUnlockModel.Buffer();
+
@VisibleForTesting
SparseArray<BiometricAuthenticated> mUserFingerprintAuthenticated = new SparseArray<>();
@VisibleForTesting
SparseArray<BiometricAuthenticated> mUserFaceAuthenticated = new SparseArray<>();
- // Keep track of recent calls to shouldListenFor*() for debugging.
- private final KeyguardListenQueue mListenModels = new KeyguardListenQueue();
-
private static int sCurrentUser;
public synchronized static void setCurrentUser(int currentUser) {
@@ -480,7 +485,7 @@
}
@Override
- public void onTrustChanged(boolean enabled, int userId, int flags,
+ public void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId, int flags,
List<String> trustGrantedMessages) {
Assert.isMainThread();
boolean wasTrusted = mUserHasTrust.get(userId, false);
@@ -510,7 +515,7 @@
}
}
- mLogger.logTrustGrantedWithFlags(flags, userId, message);
+ mLogger.logTrustGrantedWithFlags(flags, newlyUnlocked, userId, message);
if (userId == getCurrentUser()) {
final TrustGrantFlags trustGrantFlags = new TrustGrantFlags(flags);
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -518,7 +523,10 @@
if (cb != null) {
cb.onTrustGrantedForCurrentUser(
shouldDismissKeyguardOnTrustGrantedWithCurrentUser(trustGrantFlags),
- trustGrantFlags, message);
+ newlyUnlocked,
+ trustGrantFlags,
+ message
+ );
}
}
}
@@ -2647,7 +2655,7 @@
&& !mSecureCameraLaunched;
// Aggregate relevant fields for debug logging.
- maybeLogListenerModelData(
+ logListenerModelData(
new KeyguardActiveUnlockModel(
System.currentTimeMillis(),
user,
@@ -2728,7 +2736,7 @@
boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
&& shouldListenBouncerState && shouldListenUdfpsState
&& shouldListenSideFpsState;
- maybeLogListenerModelData(
+ logListenerModelData(
new KeyguardFingerprintListenModel(
System.currentTimeMillis(),
user,
@@ -2813,7 +2821,7 @@
&& !mGoingToSleep;
// Aggregate relevant fields for debug logging.
- maybeLogListenerModelData(
+ logListenerModelData(
new KeyguardFaceListenModel(
System.currentTimeMillis(),
user,
@@ -2841,28 +2849,14 @@
return shouldListen;
}
- private void maybeLogListenerModelData(@NonNull KeyguardListenModel model) {
+ private void logListenerModelData(@NonNull KeyguardListenModel model) {
mLogger.logKeyguardListenerModel(model);
-
- if (model instanceof KeyguardActiveUnlockModel) {
- mListenModels.add(model);
- return;
- }
-
- // Add model data to the historical buffer.
- final boolean notYetRunning =
- (model instanceof KeyguardFaceListenModel
- && mFaceRunningState != BIOMETRIC_STATE_RUNNING)
- || (model instanceof KeyguardFingerprintListenModel
- && mFingerprintRunningState != BIOMETRIC_STATE_RUNNING);
- final boolean running =
- (model instanceof KeyguardFaceListenModel
- && mFaceRunningState == BIOMETRIC_STATE_RUNNING)
- || (model instanceof KeyguardFingerprintListenModel
- && mFingerprintRunningState == BIOMETRIC_STATE_RUNNING);
- if (notYetRunning && model.getListening()
- || running && !model.getListening()) {
- mListenModels.add(model);
+ if (model instanceof KeyguardFingerprintListenModel) {
+ mFingerprintListenBuffer.insert((KeyguardFingerprintListenModel) model);
+ } else if (model instanceof KeyguardActiveUnlockModel) {
+ mActiveUnlockTriggerBuffer.insert((KeyguardActiveUnlockModel) model);
+ } else if (model instanceof KeyguardFaceListenModel) {
+ mFaceListenBuffer.insert((KeyguardFaceListenModel) model);
}
}
@@ -3935,6 +3929,11 @@
pw.println(" mSfpsRequireScreenOnToAuthPrefEnabled="
+ mSfpsRequireScreenOnToAuthPrefEnabled);
}
+ new DumpsysTableLogger(
+ "KeyguardFingerprintListen",
+ KeyguardFingerprintListenModel.TABLE_HEADERS,
+ mFingerprintListenBuffer.toList()
+ ).printTableData(pw);
}
if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
final int userId = mUserTracker.getUserId();
@@ -3960,7 +3959,17 @@
pw.println(" mSecureCameraLaunched=" + mSecureCameraLaunched);
pw.println(" mPrimaryBouncerFullyShown=" + mPrimaryBouncerFullyShown);
pw.println(" mNeedsSlowUnlockTransition=" + mNeedsSlowUnlockTransition);
+ new DumpsysTableLogger(
+ "KeyguardFaceListen",
+ KeyguardFaceListenModel.TABLE_HEADERS,
+ mFaceListenBuffer.toList()
+ ).printTableData(pw);
}
- mListenModels.print(pw);
+
+ new DumpsysTableLogger(
+ "KeyguardActiveUnlockTriggers",
+ KeyguardActiveUnlockModel.TABLE_HEADERS,
+ mActiveUnlockTriggerBuffer.toList()
+ ).printTableData(pw);
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 1d58fc9..e6b9ac8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -178,11 +178,17 @@
* Called after trust was granted.
* @param dismissKeyguard whether the keyguard should be dismissed as a result of the
* trustGranted
+ * @param newlyUnlocked whether the grantedTrust is believed to be the cause of a newly
+ * unlocked device (after being locked).
* @param message optional message the trust agent has provided to show that should indicate
* why trust was granted.
*/
- public void onTrustGrantedForCurrentUser(boolean dismissKeyguard,
- @NonNull TrustGrantFlags flags, @Nullable String message) { }
+ public void onTrustGrantedForCurrentUser(
+ boolean dismissKeyguard,
+ boolean newlyUnlocked,
+ @NonNull TrustGrantFlags flags,
+ @Nullable String message
+ ) { }
/**
* Called when a biometric has been acquired.
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index ceebe4c..21d3b24 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -379,14 +379,17 @@
fun logTrustGrantedWithFlags(
flags: Int,
+ newlyUnlocked: Boolean,
userId: Int,
message: String?
) {
logBuffer.log(TAG, DEBUG, {
int1 = flags
+ bool1 = newlyUnlocked
int2 = userId
str1 = message
- }, { "trustGrantedWithFlags[user=$int2] flags=${TrustGrantFlags(int1)} message=$str1" })
+ }, { "trustGrantedWithFlags[user=$int2] newlyUnlocked=$bool1 " +
+ "flags=${TrustGrantFlags(int1)} message=$str1" })
}
fun logTrustChanged(
diff --git a/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt b/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
index 4b7e9a5..98ac2c0 100644
--- a/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
+++ b/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
@@ -16,31 +16,25 @@
package com.android.keyguard.mediator
+import android.annotation.BinderThread
import android.os.Trace
-
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyguard.ScreenLifecycle
-import com.android.systemui.util.concurrency.Execution
-import com.android.systemui.util.concurrency.PendingTasksContainer
import com.android.systemui.unfold.SysUIUnfoldComponent
+import com.android.systemui.util.concurrency.PendingTasksContainer
import com.android.systemui.util.kotlin.getOrNull
-
import java.util.Optional
-
import javax.inject.Inject
/**
* Coordinates screen on/turning on animations for the KeyguardViewMediator. Specifically for
* screen on events, this will invoke the onDrawn Runnable after all tasks have completed. This
- * should route back to the KeyguardService, which informs the system_server that keyguard has
- * drawn.
+ * should route back to the [com.android.systemui.keyguard.KeyguardService], which informs
+ * the system_server that keyguard has drawn.
*/
@SysUISingleton
class ScreenOnCoordinator @Inject constructor(
- screenLifecycle: ScreenLifecycle,
- unfoldComponent: Optional<SysUIUnfoldComponent>,
- private val execution: Execution
-) : ScreenLifecycle.Observer {
+ unfoldComponent: Optional<SysUIUnfoldComponent>
+) {
private val unfoldLightRevealAnimation = unfoldComponent.map(
SysUIUnfoldComponent::getUnfoldLightRevealOverlayAnimation).getOrNull()
@@ -48,15 +42,12 @@
SysUIUnfoldComponent::getFoldAodAnimationController).getOrNull()
private val pendingTasks = PendingTasksContainer()
- init {
- screenLifecycle.addObserver(this)
- }
-
/**
* When turning on, registers tasks that may need to run before invoking [onDrawn].
+ * This is called on a binder thread from [com.android.systemui.keyguard.KeyguardService].
*/
- override fun onScreenTurningOn(onDrawn: Runnable) {
- execution.assertIsMainThread()
+ @BinderThread
+ fun onScreenTurningOn(onDrawn: Runnable) {
Trace.beginSection("ScreenOnCoordinator#onScreenTurningOn")
pendingTasks.reset()
@@ -68,11 +59,13 @@
Trace.endSection()
}
- override fun onScreenTurnedOn() {
- execution.assertIsMainThread()
-
+ /**
+ * Called when screen is fully turned on and screen on blocker is removed.
+ * This is called on a binder thread from [com.android.systemui.keyguard.KeyguardService].
+ */
+ @BinderThread
+ fun onScreenTurnedOn() {
foldAodAnimationController?.onScreenTurnedOn()
-
pendingTasks.reset()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index 63c2065..f97d6af 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -22,6 +22,7 @@
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_SHOW_ACTIONS;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_SHOW_EDIT_BUTTON;
+import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_SHOWN;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_TAPPED;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_DISMISSED_OTHER;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_DISMISS_TAPPED;
@@ -41,7 +42,6 @@
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipDescription;
-import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -51,7 +51,6 @@
import android.hardware.display.DisplayManager;
import android.hardware.input.InputManager;
import android.net.Uri;
-import android.os.AsyncTask;
import android.os.Looper;
import android.provider.DeviceConfig;
import android.text.TextUtils;
@@ -62,10 +61,6 @@
import android.view.InputEventReceiver;
import android.view.InputMonitor;
import android.view.MotionEvent;
-import android.view.textclassifier.TextClassification;
-import android.view.textclassifier.TextClassificationManager;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextLinks;
import androidx.annotation.NonNull;
@@ -74,12 +69,13 @@
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule.OverlayWindowContext;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.screenshot.TimeoutHandler;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Optional;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -102,9 +98,9 @@
private final DisplayManager mDisplayManager;
private final ClipboardOverlayWindow mWindow;
private final TimeoutHandler mTimeoutHandler;
- private final TextClassifier mTextClassifier;
private final ClipboardOverlayUtils mClipboardUtils;
private final FeatureFlags mFeatureFlags;
+ private final Executor mBgExecutor;
private final ClipboardOverlayView mView;
@@ -189,6 +185,7 @@
TimeoutHandler timeoutHandler,
FeatureFlags featureFlags,
ClipboardOverlayUtils clipboardUtils,
+ @Background Executor bgExecutor,
UiEventLogger uiEventLogger) {
mBroadcastDispatcher = broadcastDispatcher;
mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class));
@@ -204,14 +201,12 @@
hideImmediate();
});
- mTextClassifier = requireNonNull(context.getSystemService(TextClassificationManager.class))
- .getTextClassifier();
-
mTimeoutHandler = timeoutHandler;
mTimeoutHandler.setDefaultTimeoutMillis(CLIPBOARD_DEFAULT_TIMEOUT_MILLIS);
mFeatureFlags = featureFlags;
mClipboardUtils = clipboardUtils;
+ mBgExecutor = bgExecutor;
mView.setCallbacks(mClipboardCallbacks);
@@ -281,7 +276,7 @@
if (isRemote || DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
CLIPBOARD_OVERLAY_SHOW_ACTIONS, false)) {
if (item.getTextLinks() != null) {
- AsyncTask.execute(() -> classifyText(clipData.getItemAt(0), clipSource));
+ classifyText(clipData.getItemAt(0), clipSource);
}
}
if (isSensitive) {
@@ -338,22 +333,18 @@
}
private void classifyText(ClipData.Item item, String source) {
- ArrayList<RemoteAction> actions = new ArrayList<>();
- for (TextLinks.TextLink link : item.getTextLinks().getLinks()) {
- TextClassification classification = mTextClassifier.classifyText(
- item.getText(), link.getStart(), link.getEnd(), null);
- actions.addAll(classification.getActions());
- }
- mView.post(() -> {
- Optional<RemoteAction> action = actions.stream().filter(remoteAction -> {
- ComponentName component = remoteAction.getActionIntent().getIntent().getComponent();
- return component != null && !TextUtils.equals(source, component.getPackageName());
- }).findFirst();
- mView.resetActionChips();
- action.ifPresent(remoteAction -> mView.setActionChip(remoteAction, () -> {
- mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_ACTION_TAPPED);
- animateOut();
- }));
+ mBgExecutor.execute(() -> {
+ Optional<RemoteAction> action = mClipboardUtils.getAction(item, source);
+ mView.post(() -> {
+ mView.resetActionChips();
+ action.ifPresent(remoteAction -> {
+ mView.setActionChip(remoteAction, () -> {
+ mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_ACTION_TAPPED);
+ animateOut();
+ });
+ mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_ACTION_SHOWN);
+ });
+ });
});
}
@@ -539,6 +530,10 @@
mClipSource = clipSource;
}
+ void logUnguarded(@NonNull UiEventLogger.UiEventEnum event) {
+ mUiEventLogger.log(event, 0, mClipSource);
+ }
+
void logSessionComplete(@NonNull UiEventLogger.UiEventEnum event) {
if (!mGuarded) {
mGuarded = true;
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java
index a0b2ab9..9917507 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java
@@ -28,6 +28,8 @@
CLIPBOARD_OVERLAY_EDIT_TAPPED(951),
@UiEvent(doc = "clipboard share tapped")
CLIPBOARD_OVERLAY_SHARE_TAPPED(1067),
+ @UiEvent(doc = "clipboard smart action shown")
+ CLIPBOARD_OVERLAY_ACTION_SHOWN(1260),
@UiEvent(doc = "clipboard action tapped")
CLIPBOARD_OVERLAY_ACTION_TAPPED(952),
@UiEvent(doc = "clipboard remote copy tapped")
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java
index c194e66..785e4a0 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java
@@ -16,22 +16,34 @@
package com.android.systemui.clipboardoverlay;
+import android.app.RemoteAction;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ComponentName;
import android.content.Context;
import android.os.Build;
import android.provider.DeviceConfig;
+import android.text.TextUtils;
+import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationManager;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextLinks;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.systemui.R;
+import java.util.ArrayList;
+import java.util.Optional;
+
import javax.inject.Inject;
class ClipboardOverlayUtils {
+ private final TextClassifier mTextClassifier;
+
@Inject
- ClipboardOverlayUtils() {
+ ClipboardOverlayUtils(TextClassificationManager textClassificationManager) {
+ mTextClassifier = textClassificationManager.getTextClassifier();
}
boolean isRemoteCopy(Context context, ClipData clipData, String clipSource) {
@@ -52,4 +64,21 @@
}
return false;
}
+
+ public Optional<RemoteAction> getAction(ClipData.Item item, String source) {
+ return getActions(item).stream().filter(remoteAction -> {
+ ComponentName component = remoteAction.getActionIntent().getIntent().getComponent();
+ return component != null && !TextUtils.equals(source, component.getPackageName());
+ }).findFirst();
+ }
+
+ private ArrayList<RemoteAction> getActions(ClipData.Item item) {
+ ArrayList<RemoteAction> actions = new ArrayList<>();
+ for (TextLinks.TextLink link : item.getTextLinks().getLinks()) {
+ TextClassification classification = mTextClassifier.classifyText(
+ item.getText(), link.getStart(), link.getEnd(), null);
+ actions.addAll(classification.getActions());
+ }
+ return actions;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index 7864f19..2260e35 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -71,6 +71,7 @@
import android.os.PowerExemptionManager;
import android.os.PowerManager;
import android.os.ServiceManager;
+import android.os.SystemUpdateManager;
import android.os.UserManager;
import android.os.Vibrator;
import android.os.storage.StorageManager;
@@ -92,6 +93,9 @@
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.CaptioningManager;
import android.view.inputmethod.InputMethodManager;
+import android.view.textclassifier.TextClassificationManager;
+
+import androidx.core.app.NotificationManagerCompat;
import com.android.internal.app.IBatteryStats;
import com.android.internal.appwidget.IAppWidgetService;
@@ -136,6 +140,12 @@
return context.getSystemService(AlarmManager.class);
}
+ @Provides
+ @Singleton
+ static Optional<SystemUpdateManager> provideSystemUpdateManager(Context context) {
+ return Optional.ofNullable(context.getSystemService(SystemUpdateManager.class));
+ }
+
/** */
@Provides
public AmbientDisplayConfiguration provideAmbientDisplayConfiguration(Context context) {
@@ -389,6 +399,12 @@
return context.getSystemService(NotificationManager.class);
}
+ @Provides
+ @Singleton
+ static NotificationManagerCompat provideNotificationManagerCompat(Context context) {
+ return NotificationManagerCompat.from(context);
+ }
+
/** */
@Provides
@Singleton
@@ -623,4 +639,10 @@
static BluetoothAdapter provideBluetoothAdapter(BluetoothManager bluetoothManager) {
return bluetoothManager.getAdapter();
}
+
+ @Provides
+ @Singleton
+ static TextClassificationManager provideTextClassificationManager(Context context) {
+ return context.getSystemService(TextClassificationManager.class);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 0fbe0ac..4db77ab 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -40,8 +40,11 @@
import com.android.systemui.recents.Recents
import com.android.systemui.settings.dagger.MultiUserUtilsModule
import com.android.systemui.shortcut.ShortcutKeyDispatcher
+import com.android.systemui.statusbar.notification.fsi.FsiChromeRepo
import com.android.systemui.statusbar.notification.InstantAppNotifier
+import com.android.systemui.statusbar.notification.fsi.FsiChromeViewModelFactory
import com.android.systemui.statusbar.phone.KeyguardLiftController
+import com.android.systemui.stylus.StylusUsiPowerStartable
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import com.android.systemui.theme.ThemeOverlayController
import com.android.systemui.toast.ToastUI
@@ -78,6 +81,18 @@
@ClassKey(ClipboardListener::class)
abstract fun bindClipboardListener(sysui: ClipboardListener): CoreStartable
+ /** Inject into FsiChromeRepo. */
+ @Binds
+ @IntoMap
+ @ClassKey(FsiChromeRepo::class)
+ abstract fun bindFSIChromeRepo(sysui: FsiChromeRepo): CoreStartable
+
+ /** Inject into FsiChromeWindowViewModel. */
+ @Binds
+ @IntoMap
+ @ClassKey(FsiChromeViewModelFactory::class)
+ abstract fun bindFSIChromeWindowViewModel(sysui: FsiChromeViewModelFactory): CoreStartable
+
/** Inject into GarbageMonitor.Service. */
@Binds
@IntoMap
@@ -251,4 +266,10 @@
@IntoMap
@ClassKey(RearDisplayDialogController::class)
abstract fun bindRearDisplayDialogController(sysui: RearDisplayDialogController): CoreStartable
+
+ /** Inject into StylusUsiPowerStartable) */
+ @Binds
+ @IntoMap
+ @ClassKey(StylusUsiPowerStartable::class)
+ abstract fun bindStylusUsiPowerStartable(sysui: StylusUsiPowerStartable): CoreStartable
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamCallbackController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamCallbackController.kt
new file mode 100644
index 0000000..ab4632b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamCallbackController.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.policy.CallbackController
+import javax.inject.Inject
+
+/** Dream-related callback information */
+@SysUISingleton
+class DreamCallbackController @Inject constructor() :
+ CallbackController<DreamCallbackController.DreamCallback> {
+
+ private val callbacks = mutableSetOf<DreamCallbackController.DreamCallback>()
+
+ override fun addCallback(callback: DreamCallbackController.DreamCallback) {
+ callbacks.add(callback)
+ }
+
+ override fun removeCallback(callback: DreamCallbackController.DreamCallback) {
+ callbacks.remove(callback)
+ }
+
+ fun onWakeUp() {
+ callbacks.forEach { it.onWakeUp() }
+ }
+
+ interface DreamCallback {
+ fun onWakeUp()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
index 0087c84..abe9355 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
@@ -21,17 +21,31 @@
import android.animation.ValueAnimator
import android.view.View
import android.view.animation.Interpolator
-import androidx.annotation.FloatRange
import androidx.core.animation.doOnEnd
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.R
import com.android.systemui.animation.Interpolators
import com.android.systemui.dreams.complication.ComplicationHostViewController
import com.android.systemui.dreams.complication.ComplicationLayoutParams
+import com.android.systemui.dreams.complication.ComplicationLayoutParams.POSITION_BOTTOM
+import com.android.systemui.dreams.complication.ComplicationLayoutParams.POSITION_TOP
import com.android.systemui.dreams.complication.ComplicationLayoutParams.Position
import com.android.systemui.dreams.dagger.DreamOverlayModule
+import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.Companion.DREAM_ANIMATION_DURATION
+import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.BlurUtils
import com.android.systemui.statusbar.CrossFadeHelper
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
+import com.android.systemui.util.concurrency.DelayableExecutor
import javax.inject.Inject
import javax.inject.Named
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.launch
/** Controller for dream overlay animations. */
class DreamOverlayAnimationsController
@@ -41,32 +55,21 @@
private val mComplicationHostViewController: ComplicationHostViewController,
private val mStatusBarViewController: DreamOverlayStatusBarViewController,
private val mOverlayStateController: DreamOverlayStateController,
+ @Named(DreamOverlayModule.DREAM_BLUR_RADIUS) private val mDreamBlurRadius: Int,
+ private val transitionViewModel: DreamingToLockscreenTransitionViewModel,
+ private val configController: ConfigurationController,
@Named(DreamOverlayModule.DREAM_IN_BLUR_ANIMATION_DURATION)
private val mDreamInBlurAnimDurationMs: Long,
- @Named(DreamOverlayModule.DREAM_IN_BLUR_ANIMATION_DELAY)
- private val mDreamInBlurAnimDelayMs: Long,
@Named(DreamOverlayModule.DREAM_IN_COMPLICATIONS_ANIMATION_DURATION)
private val mDreamInComplicationsAnimDurationMs: Long,
- @Named(DreamOverlayModule.DREAM_IN_TOP_COMPLICATIONS_ANIMATION_DELAY)
- private val mDreamInTopComplicationsAnimDelayMs: Long,
- @Named(DreamOverlayModule.DREAM_IN_BOTTOM_COMPLICATIONS_ANIMATION_DELAY)
- private val mDreamInBottomComplicationsAnimDelayMs: Long,
- @Named(DreamOverlayModule.DREAM_OUT_TRANSLATION_Y_DISTANCE)
- private val mDreamOutTranslationYDistance: Int,
- @Named(DreamOverlayModule.DREAM_OUT_TRANSLATION_Y_DURATION)
- private val mDreamOutTranslationYDurationMs: Long,
- @Named(DreamOverlayModule.DREAM_OUT_TRANSLATION_Y_DELAY_BOTTOM)
- private val mDreamOutTranslationYDelayBottomMs: Long,
- @Named(DreamOverlayModule.DREAM_OUT_TRANSLATION_Y_DELAY_TOP)
- private val mDreamOutTranslationYDelayTopMs: Long,
- @Named(DreamOverlayModule.DREAM_OUT_ALPHA_DURATION) private val mDreamOutAlphaDurationMs: Long,
- @Named(DreamOverlayModule.DREAM_OUT_ALPHA_DELAY_BOTTOM)
- private val mDreamOutAlphaDelayBottomMs: Long,
- @Named(DreamOverlayModule.DREAM_OUT_ALPHA_DELAY_TOP) private val mDreamOutAlphaDelayTopMs: Long,
- @Named(DreamOverlayModule.DREAM_OUT_BLUR_DURATION) private val mDreamOutBlurDurationMs: Long
+ @Named(DreamOverlayModule.DREAM_IN_TRANSLATION_Y_DISTANCE)
+ private val mDreamInTranslationYDistance: Int,
+ @Named(DreamOverlayModule.DREAM_IN_TRANSLATION_Y_DURATION)
+ private val mDreamInTranslationYDurationMs: Long,
) {
private var mAnimator: Animator? = null
+ private lateinit var view: View
/**
* Store the current alphas at the various positions. This is so that we may resume an animation
@@ -74,11 +77,65 @@
*/
private var mCurrentAlphaAtPosition = mutableMapOf<Int, Float>()
- @FloatRange(from = 0.0, to = 1.0) private var mBlurProgress: Float = 0f
+ private var mCurrentBlurRadius: Float = 0f
+
+ fun init(view: View) {
+ this.view = view
+
+ view.repeatWhenAttached {
+ val configurationBasedDimensions = MutableStateFlow(loadFromResources(view))
+ val configCallback =
+ object : ConfigurationListener {
+ override fun onDensityOrFontScaleChanged() {
+ configurationBasedDimensions.value = loadFromResources(view)
+ }
+ }
+
+ configController.addCallback(configCallback)
+
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
+ /* Translation animations, when moving from DREAMING->LOCKSCREEN state */
+ launch {
+ configurationBasedDimensions
+ .flatMapLatest {
+ transitionViewModel.dreamOverlayTranslationY(it.translationYPx)
+ }
+ .collect { px ->
+ setElementsTranslationYAtPosition(
+ px,
+ ComplicationLayoutParams.POSITION_TOP
+ )
+ setElementsTranslationYAtPosition(
+ px,
+ ComplicationLayoutParams.POSITION_BOTTOM
+ )
+ }
+ }
+
+ /* Alpha animations, when moving from DREAMING->LOCKSCREEN state */
+ launch {
+ transitionViewModel.dreamOverlayAlpha.collect { alpha ->
+ setElementsAlphaAtPosition(
+ alpha = alpha,
+ position = ComplicationLayoutParams.POSITION_TOP,
+ fadingOut = true,
+ )
+ setElementsAlphaAtPosition(
+ alpha = alpha,
+ position = ComplicationLayoutParams.POSITION_BOTTOM,
+ fadingOut = true,
+ )
+ }
+ }
+ }
+
+ configController.removeCallback(configCallback)
+ }
+ }
/** Starts the dream content and dream overlay entry animations. */
@JvmOverloads
- fun startEntryAnimations(view: View, animatorBuilder: () -> AnimatorSet = { AnimatorSet() }) {
+ fun startEntryAnimations(animatorBuilder: () -> AnimatorSet = { AnimatorSet() }) {
cancelAnimations()
mAnimator =
@@ -86,25 +143,23 @@
playTogether(
blurAnimator(
view = view,
- from = 1f,
- to = 0f,
+ fromBlurRadius = mDreamBlurRadius.toFloat(),
+ toBlurRadius = 0f,
durationMs = mDreamInBlurAnimDurationMs,
- delayMs = mDreamInBlurAnimDelayMs
+ interpolator = Interpolators.EMPHASIZED_DECELERATE
),
alphaAnimator(
from = 0f,
to = 1f,
durationMs = mDreamInComplicationsAnimDurationMs,
- delayMs = mDreamInTopComplicationsAnimDelayMs,
- position = ComplicationLayoutParams.POSITION_TOP
+ interpolator = Interpolators.LINEAR
),
- alphaAnimator(
- from = 0f,
- to = 1f,
- durationMs = mDreamInComplicationsAnimDurationMs,
- delayMs = mDreamInBottomComplicationsAnimDelayMs,
- position = ComplicationLayoutParams.POSITION_BOTTOM
- )
+ translationYAnimator(
+ from = mDreamInTranslationYDistance.toFloat(),
+ to = 0f,
+ durationMs = mDreamInTranslationYDurationMs,
+ interpolator = Interpolators.EMPHASIZED_DECELERATE
+ ),
)
doOnEnd {
mAnimator = null
@@ -115,72 +170,9 @@
}
/** Starts the dream content and dream overlay exit animations. */
- @JvmOverloads
- fun startExitAnimations(
- view: View,
- doneCallback: () -> Unit,
- animatorBuilder: () -> AnimatorSet = { AnimatorSet() }
- ) {
+ fun wakeUp(doneCallback: Runnable, executor: DelayableExecutor) {
cancelAnimations()
-
- mAnimator =
- animatorBuilder().apply {
- playTogether(
- blurAnimator(
- view = view,
- // Start the blurring wherever the entry animation ended, in
- // case it was cancelled early.
- from = mBlurProgress,
- to = 1f,
- durationMs = mDreamOutBlurDurationMs
- ),
- translationYAnimator(
- from = 0f,
- to = mDreamOutTranslationYDistance.toFloat(),
- durationMs = mDreamOutTranslationYDurationMs,
- delayMs = mDreamOutTranslationYDelayBottomMs,
- position = ComplicationLayoutParams.POSITION_BOTTOM,
- animInterpolator = Interpolators.EMPHASIZED_ACCELERATE
- ),
- translationYAnimator(
- from = 0f,
- to = mDreamOutTranslationYDistance.toFloat(),
- durationMs = mDreamOutTranslationYDurationMs,
- delayMs = mDreamOutTranslationYDelayTopMs,
- position = ComplicationLayoutParams.POSITION_TOP,
- animInterpolator = Interpolators.EMPHASIZED_ACCELERATE
- ),
- alphaAnimator(
- from =
- mCurrentAlphaAtPosition.getOrDefault(
- key = ComplicationLayoutParams.POSITION_BOTTOM,
- defaultValue = 1f
- ),
- to = 0f,
- durationMs = mDreamOutAlphaDurationMs,
- delayMs = mDreamOutAlphaDelayBottomMs,
- position = ComplicationLayoutParams.POSITION_BOTTOM
- ),
- alphaAnimator(
- from =
- mCurrentAlphaAtPosition.getOrDefault(
- key = ComplicationLayoutParams.POSITION_TOP,
- defaultValue = 1f
- ),
- to = 0f,
- durationMs = mDreamOutAlphaDurationMs,
- delayMs = mDreamOutAlphaDelayTopMs,
- position = ComplicationLayoutParams.POSITION_TOP
- )
- )
- doOnEnd {
- mAnimator = null
- mOverlayStateController.setExitAnimationsRunning(false)
- doneCallback()
- }
- start()
- }
- mOverlayStateController.setExitAnimationsRunning(true)
+ executor.executeDelayed(doneCallback, DREAM_ANIMATION_DURATION.inWholeMilliseconds)
}
/** Cancels the dream content and dream overlay animations, if they're currently running. */
@@ -194,20 +186,21 @@
private fun blurAnimator(
view: View,
- from: Float,
- to: Float,
+ fromBlurRadius: Float,
+ toBlurRadius: Float,
durationMs: Long,
- delayMs: Long = 0
+ delayMs: Long = 0,
+ interpolator: Interpolator = Interpolators.LINEAR
): Animator {
- return ValueAnimator.ofFloat(from, to).apply {
+ return ValueAnimator.ofFloat(fromBlurRadius, toBlurRadius).apply {
duration = durationMs
startDelay = delayMs
- interpolator = Interpolators.LINEAR
+ this.interpolator = interpolator
addUpdateListener { animator: ValueAnimator ->
- mBlurProgress = animator.animatedValue as Float
+ mCurrentBlurRadius = animator.animatedValue as Float
mBlurUtils.applyBlur(
viewRootImpl = view.viewRootImpl,
- radius = mBlurUtils.blurRadiusOfRatio(mBlurProgress).toInt(),
+ radius = mCurrentBlurRadius.toInt(),
opaque = false
)
}
@@ -218,18 +211,24 @@
from: Float,
to: Float,
durationMs: Long,
- delayMs: Long,
- @Position position: Int
+ delayMs: Long = 0,
+ @Position positions: Int = POSITION_TOP or POSITION_BOTTOM,
+ interpolator: Interpolator = Interpolators.LINEAR
): Animator {
return ValueAnimator.ofFloat(from, to).apply {
duration = durationMs
startDelay = delayMs
- interpolator = Interpolators.LINEAR
+ this.interpolator = interpolator
addUpdateListener { va: ValueAnimator ->
- setElementsAlphaAtPosition(
- alpha = va.animatedValue as Float,
- position = position,
- fadingOut = to < from
+ ComplicationLayoutParams.iteratePositions(
+ { position: Int ->
+ setElementsAlphaAtPosition(
+ alpha = va.animatedValue as Float,
+ position = position,
+ fadingOut = to < from
+ )
+ },
+ positions
)
}
}
@@ -239,16 +238,21 @@
from: Float,
to: Float,
durationMs: Long,
- delayMs: Long,
- @Position position: Int,
- animInterpolator: Interpolator
+ delayMs: Long = 0,
+ @Position positions: Int = POSITION_TOP or POSITION_BOTTOM,
+ interpolator: Interpolator = Interpolators.LINEAR
): Animator {
return ValueAnimator.ofFloat(from, to).apply {
duration = durationMs
startDelay = delayMs
- interpolator = animInterpolator
+ this.interpolator = interpolator
addUpdateListener { va: ValueAnimator ->
- setElementsTranslationYAtPosition(va.animatedValue as Float, position)
+ ComplicationLayoutParams.iteratePositions(
+ { position: Int ->
+ setElementsTranslationYAtPosition(va.animatedValue as Float, position)
+ },
+ positions
+ )
}
}
}
@@ -263,7 +267,7 @@
CrossFadeHelper.fadeIn(view, alpha, /* remap= */ false)
}
}
- if (position == ComplicationLayoutParams.POSITION_TOP) {
+ if (position == POSITION_TOP) {
mStatusBarViewController.setFadeAmount(alpha, fadingOut)
}
}
@@ -273,8 +277,19 @@
mComplicationHostViewController.getViewsAtPosition(position).forEach { v ->
v.translationY = translationY
}
- if (position == ComplicationLayoutParams.POSITION_TOP) {
+ if (position == POSITION_TOP) {
mStatusBarViewController.setTranslationY(translationY)
}
}
+
+ private fun loadFromResources(view: View): ConfigurationBasedDimensions {
+ return ConfigurationBasedDimensions(
+ translationYPx =
+ view.resources.getDimensionPixelSize(R.dimen.dream_overlay_exit_y_offset),
+ )
+ }
+
+ private data class ConfigurationBasedDimensions(
+ val translationYPx: Int,
+ )
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 9d7ad30..3106173 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -42,9 +42,9 @@
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.util.ViewController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
import java.util.Arrays;
-import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
@@ -170,6 +170,7 @@
protected void onInit() {
mStatusBarViewController.init();
mComplicationHostViewController.init();
+ mDreamOverlayAnimationsController.init(mView);
}
@Override
@@ -184,7 +185,7 @@
// Start dream entry animations. Skip animations for low light clock.
if (!mStateController.isLowLightActive()) {
- mDreamOverlayAnimationsController.startEntryAnimations(mView);
+ mDreamOverlayAnimationsController.startEntryAnimations();
}
}
@@ -261,10 +262,8 @@
* @param onAnimationEnd Callback to trigger once animations are finished.
* @param callbackExecutor Executor to execute the callback on.
*/
- public void wakeUp(@NonNull Runnable onAnimationEnd, @NonNull Executor callbackExecutor) {
- mDreamOverlayAnimationsController.startExitAnimations(mView, () -> {
- callbackExecutor.execute(onAnimationEnd);
- return null;
- });
+ public void wakeUp(@NonNull Runnable onAnimationEnd,
+ @NonNull DelayableExecutor callbackExecutor) {
+ mDreamOverlayAnimationsController.wakeUp(onAnimationEnd, callbackExecutor);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index e76d5b3..1be9cd1 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -43,8 +43,7 @@
import com.android.systemui.dreams.complication.Complication;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;
-
-import java.util.concurrent.Executor;
+import com.android.systemui.util.concurrency.DelayableExecutor;
import javax.inject.Inject;
import javax.inject.Named;
@@ -61,10 +60,11 @@
// The Context is used to construct the hosting constraint layout and child overlay views.
private final Context mContext;
// The Executor ensures actions and ui updates happen on the same thread.
- private final Executor mExecutor;
+ private final DelayableExecutor mExecutor;
// A controller for the dream overlay container view (which contains both the status bar and the
// content area).
private DreamOverlayContainerViewController mDreamOverlayContainerViewController;
+ private final DreamCallbackController mDreamCallbackController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Nullable
private final ComponentName mLowLightDreamComponent;
@@ -126,14 +126,15 @@
@Inject
public DreamOverlayService(
Context context,
- @Main Executor executor,
+ @Main DelayableExecutor executor,
WindowManager windowManager,
DreamOverlayComponent.Factory dreamOverlayComponentFactory,
DreamOverlayStateController stateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
UiEventLogger uiEventLogger,
@Nullable @Named(LowLightDreamModule.LOW_LIGHT_DREAM_COMPONENT)
- ComponentName lowLightDreamComponent) {
+ ComponentName lowLightDreamComponent,
+ DreamCallbackController dreamCallbackController) {
mContext = context;
mExecutor = executor;
mWindowManager = windowManager;
@@ -142,6 +143,7 @@
mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback);
mStateController = stateController;
mUiEventLogger = uiEventLogger;
+ mDreamCallbackController = dreamCallbackController;
final ViewModelStore viewModelStore = new ViewModelStore();
final Complication.Host host =
@@ -217,6 +219,7 @@
public void onWakeUp(@NonNull Runnable onCompletedCallback) {
mExecutor.execute(() -> {
if (mDreamOverlayContainerViewController != null) {
+ mDreamCallbackController.onWakeUp();
mDreamOverlayContainerViewController.wakeUp(onCompletedCallback, mExecutor);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutParams.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutParams.java
index 1755cb92..99e19fc 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutParams.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutParams.java
@@ -251,9 +251,17 @@
* position specified for this {@link ComplicationLayoutParams}.
*/
public void iteratePositions(Consumer<Integer> consumer) {
+ iteratePositions(consumer, mPosition);
+ }
+
+ /**
+ * Iterates over the defined positions and invokes the specified {@link Consumer} for each
+ * position specified by the given {@code position}.
+ */
+ public static void iteratePositions(Consumer<Integer> consumer, @Position int position) {
for (int currentPosition = FIRST_POSITION; currentPosition <= LAST_POSITION;
currentPosition <<= 1) {
- if ((mPosition & currentPosition) == currentPosition) {
+ if ((position & currentPosition) == currentPosition) {
consumer.accept(currentPosition);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
index ed0e1d9..0d58a69 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
@@ -47,30 +47,14 @@
public static final String BURN_IN_PROTECTION_UPDATE_INTERVAL =
"burn_in_protection_update_interval";
public static final String MILLIS_UNTIL_FULL_JITTER = "millis_until_full_jitter";
+ public static final String DREAM_BLUR_RADIUS = "DREAM_BLUR_RADIUS";
public static final String DREAM_IN_BLUR_ANIMATION_DURATION = "dream_in_blur_anim_duration";
- public static final String DREAM_IN_BLUR_ANIMATION_DELAY = "dream_in_blur_anim_delay";
public static final String DREAM_IN_COMPLICATIONS_ANIMATION_DURATION =
"dream_in_complications_anim_duration";
- public static final String DREAM_IN_TOP_COMPLICATIONS_ANIMATION_DELAY =
- "dream_in_top_complications_anim_delay";
- public static final String DREAM_IN_BOTTOM_COMPLICATIONS_ANIMATION_DELAY =
- "dream_in_bottom_complications_anim_delay";
- public static final String DREAM_OUT_TRANSLATION_Y_DISTANCE =
- "dream_out_complications_translation_y";
- public static final String DREAM_OUT_TRANSLATION_Y_DURATION =
- "dream_out_complications_translation_y_duration";
- public static final String DREAM_OUT_TRANSLATION_Y_DELAY_BOTTOM =
- "dream_out_complications_translation_y_delay_bottom";
- public static final String DREAM_OUT_TRANSLATION_Y_DELAY_TOP =
- "dream_out_complications_translation_y_delay_top";
- public static final String DREAM_OUT_ALPHA_DURATION =
- "dream_out_complications_alpha_duration";
- public static final String DREAM_OUT_ALPHA_DELAY_BOTTOM =
- "dream_out_complications_alpha_delay_bottom";
- public static final String DREAM_OUT_ALPHA_DELAY_TOP =
- "dream_out_complications_alpha_delay_top";
- public static final String DREAM_OUT_BLUR_DURATION =
- "dream_out_blur_duration";
+ public static final String DREAM_IN_TRANSLATION_Y_DISTANCE =
+ "dream_in_complications_translation_y";
+ public static final String DREAM_IN_TRANSLATION_Y_DURATION =
+ "dream_in_complications_translation_y_duration";
/** */
@Provides
@@ -139,6 +123,15 @@
}
/**
+ * The blur radius applied to the dream overlay at dream entry and exit.
+ */
+ @Provides
+ @Named(DREAM_BLUR_RADIUS)
+ static int providesDreamBlurRadius(@Main Resources resources) {
+ return resources.getDimensionPixelSize(R.dimen.dream_overlay_anim_blur_radius);
+ }
+
+ /**
* Duration in milliseconds of the dream in un-blur animation.
*/
@Provides
@@ -148,15 +141,6 @@
}
/**
- * Delay in milliseconds of the dream in un-blur animation.
- */
- @Provides
- @Named(DREAM_IN_BLUR_ANIMATION_DELAY)
- static long providesDreamInBlurAnimationDelay(@Main Resources resources) {
- return (long) resources.getInteger(R.integer.config_dreamOverlayInBlurDelayMs);
- }
-
- /**
* Duration in milliseconds of the dream in complications fade-in animation.
*/
@Provides
@@ -166,82 +150,23 @@
}
/**
- * Delay in milliseconds of the dream in top complications fade-in animation.
+ * Provides the number of pixels to translate complications when entering a dream.
*/
@Provides
- @Named(DREAM_IN_TOP_COMPLICATIONS_ANIMATION_DELAY)
- static long providesDreamInTopComplicationsAnimationDelay(@Main Resources resources) {
- return (long) resources.getInteger(R.integer.config_dreamOverlayInTopComplicationsDelayMs);
+ @Named(DREAM_IN_TRANSLATION_Y_DISTANCE)
+ @DreamOverlayComponent.DreamOverlayScope
+ static int providesDreamInComplicationsTranslationY(@Main Resources resources) {
+ return resources.getDimensionPixelSize(R.dimen.dream_overlay_entry_y_offset);
}
/**
- * Delay in milliseconds of the dream in bottom complications fade-in animation.
+ * Provides the duration in ms of the y-translation when dream enters.
*/
@Provides
- @Named(DREAM_IN_BOTTOM_COMPLICATIONS_ANIMATION_DELAY)
- static long providesDreamInBottomComplicationsAnimationDelay(@Main Resources resources) {
- return (long) resources.getInteger(
- R.integer.config_dreamOverlayInBottomComplicationsDelayMs);
- }
-
- /**
- * Provides the number of pixels to translate complications when waking up from dream.
- */
- @Provides
- @Named(DREAM_OUT_TRANSLATION_Y_DISTANCE)
+ @Named(DREAM_IN_TRANSLATION_Y_DURATION)
@DreamOverlayComponent.DreamOverlayScope
- static int providesDreamOutComplicationsTranslationY(@Main Resources resources) {
- return resources.getDimensionPixelSize(R.dimen.dream_overlay_exit_y_offset);
- }
-
- @Provides
- @Named(DREAM_OUT_TRANSLATION_Y_DURATION)
- @DreamOverlayComponent.DreamOverlayScope
- static long providesDreamOutComplicationsTranslationYDuration(@Main Resources resources) {
- return (long) resources.getInteger(R.integer.config_dreamOverlayOutTranslationYDurationMs);
- }
-
- @Provides
- @Named(DREAM_OUT_TRANSLATION_Y_DELAY_BOTTOM)
- @DreamOverlayComponent.DreamOverlayScope
- static long providesDreamOutComplicationsTranslationYDelayBottom(@Main Resources resources) {
- return (long) resources.getInteger(
- R.integer.config_dreamOverlayOutTranslationYDelayBottomMs);
- }
-
- @Provides
- @Named(DREAM_OUT_TRANSLATION_Y_DELAY_TOP)
- @DreamOverlayComponent.DreamOverlayScope
- static long providesDreamOutComplicationsTranslationYDelayTop(@Main Resources resources) {
- return (long) resources.getInteger(R.integer.config_dreamOverlayOutTranslationYDelayTopMs);
- }
-
- @Provides
- @Named(DREAM_OUT_ALPHA_DURATION)
- @DreamOverlayComponent.DreamOverlayScope
- static long providesDreamOutComplicationsAlphaDuration(@Main Resources resources) {
- return (long) resources.getInteger(R.integer.config_dreamOverlayOutAlphaDurationMs);
- }
-
- @Provides
- @Named(DREAM_OUT_ALPHA_DELAY_BOTTOM)
- @DreamOverlayComponent.DreamOverlayScope
- static long providesDreamOutComplicationsAlphaDelayBottom(@Main Resources resources) {
- return (long) resources.getInteger(R.integer.config_dreamOverlayOutAlphaDelayBottomMs);
- }
-
- @Provides
- @Named(DREAM_OUT_ALPHA_DELAY_TOP)
- @DreamOverlayComponent.DreamOverlayScope
- static long providesDreamOutComplicationsAlphaDelayTop(@Main Resources resources) {
- return (long) resources.getInteger(R.integer.config_dreamOverlayOutAlphaDelayTopMs);
- }
-
- @Provides
- @Named(DREAM_OUT_BLUR_DURATION)
- @DreamOverlayComponent.DreamOverlayScope
- static long providesDreamOutBlurDuration(@Main Resources resources) {
- return (long) resources.getInteger(R.integer.config_dreamOverlayOutBlurDurationMs);
+ static long providesDreamInComplicationsTranslationYDuration(@Main Resources resources) {
+ return (long) resources.getInteger(R.integer.config_dreamOverlayInTranslationYDurationMs);
}
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
index c982131..276a290 100644
--- a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
@@ -51,6 +51,11 @@
registerDumpable(name, module, DumpPriority.CRITICAL)
}
+ /** See [registerNormalDumpable]. */
+ fun registerNormalDumpable(module: Dumpable) {
+ registerNormalDumpable(module::class.java.simpleName, module)
+ }
+
/**
* Registers a dumpable to be called during the NORMAL section of the bug report.
*
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index efb513d..339fd13 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -103,6 +103,11 @@
// TODO(b/257315550): Tracking Bug
val NO_HUN_FOR_OLD_WHEN = unreleasedFlag(118, "no_hun_for_old_when", teamfood = true)
+ // TODO(b/260335638): Tracking Bug
+ @JvmField
+ val NOTIFICATION_INLINE_REPLY_ANIMATION =
+ unreleasedFlag(174148361, "notification_inline_reply_animation", teamfood = true)
+
val FILTER_UNSEEN_NOTIFS_ON_KEYGUARD =
unreleasedFlag(254647461, "filter_unseen_notifs_on_keyguard", teamfood = true)
@@ -165,7 +170,9 @@
/** Shows chipbar UI whenever the device is unlocked by ActiveUnlock (watch). */
// TODO(b/256513609): Tracking Bug
- @JvmField val ACTIVE_UNLOCK_CHIPBAR = releasedFlag(217, "active_unlock_chipbar")
+ @JvmField
+ val ACTIVE_UNLOCK_CHIPBAR =
+ resourceBooleanFlag(217, R.bool.flag_active_unlock_chipbar, "active_unlock_chipbar")
/**
* Migrates control of the LightRevealScrim's reveal effect and amount from legacy code to the
@@ -174,6 +181,18 @@
@JvmField
val LIGHT_REVEAL_MIGRATION = unreleasedFlag(218, "light_reveal_migration", teamfood = false)
+ // TODO(b/262780002): Tracking Bug
+ @JvmField
+ val REVAMPED_WALLPAPER_UI = unreleasedFlag(222, "revamped_wallpaper_ui", teamfood = false)
+
+ /** Flag to control the migration of face auth to modern architecture. */
+ // TODO(b/262838215): Tracking bug
+ @JvmField val FACE_AUTH_REFACTOR = unreleasedFlag(220, "face_auth_refactor")
+
+ /** Flag to control the revamp of keyguard biometrics progress animation */
+ // TODO(b/244313043): Tracking bug
+ @JvmField val BIOMETRICS_ANIMATION_REVAMP = unreleasedFlag(221, "biometrics_animation_revamp")
+
// 300 - power menu
// TODO(b/254512600): Tracking Bug
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
@@ -265,7 +284,7 @@
// 900 - media
// TODO(b/254512697): Tracking Bug
- val MEDIA_TAP_TO_TRANSFER = releasedFlag(900, "media_tap_to_transfer")
+ val MEDIA_TAP_TO_TRANSFER = unreleasedFlag(900, "media_tap_to_transfer", teamfood = true)
// TODO(b/254512502): Tracking Bug
val MEDIA_SESSION_ACTIONS = unreleasedFlag(901, "media_session_actions")
@@ -396,6 +415,10 @@
// TODO(b/254512756): Tracking Bug
val QUICK_TAP_IN_PCC = releasedFlag(1400, "quick_tap_in_pcc")
+ // TODO(b/261979569): Tracking Bug
+ val QUICK_TAP_FLOW_FRAMEWORK =
+ unreleasedFlag(1401, "quick_tap_flow_framework", teamfood = false)
+
// 1500 - chooser
// TODO(b/254512507): Tracking Bug
val CHOOSER_UNBUNDLED = unreleasedFlag(1500, "chooser_unbundled", teamfood = true)
@@ -449,6 +472,11 @@
// TODO(b/261538825): Tracking Bug
@JvmField
val OUTPUT_SWITCHER_ADVANCED_LAYOUT = unreleasedFlag(2500, "output_switcher_advanced_layout")
+ @JvmField
+ val OUTPUT_SWITCHER_ROUTES_PROCESSING =
+ unreleasedFlag(2501, "output_switcher_routes_processing")
+ @JvmField
+ val OUTPUT_SWITCHER_DEVICE_STATUS = unreleasedFlag(2502, "output_switcher_device_status")
// TODO(b259590361): Tracking bug
val EXPERIMENTAL_FLAG = unreleasedFlag(2, "exp_flag_release")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
index 822b1cf..757afb6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
@@ -18,11 +18,8 @@
import android.os.Handler;
import android.os.Message;
-import android.os.RemoteException;
import android.os.Trace;
-import android.util.Log;
-import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.systemui.dagger.SysUISingleton;
import javax.inject.Inject;
@@ -80,33 +77,10 @@
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- final Object obj = msg.obj;
switch (msg.what) {
case SCREEN_TURNING_ON:
Trace.beginSection("KeyguardLifecyclesDispatcher#SCREEN_TURNING_ON");
- final String onDrawWaitingTraceTag =
- "Waiting for KeyguardDrawnCallback#onDrawn";
- int traceCookie = System.identityHashCode(msg);
- Trace.beginAsyncSection(onDrawWaitingTraceTag, traceCookie);
- // Ensure the drawn callback is only ever called once
- mScreenLifecycle.dispatchScreenTurningOn(new Runnable() {
- boolean mInvoked;
- @Override
- public void run() {
- if (obj == null) return;
- if (!mInvoked) {
- mInvoked = true;
- try {
- Trace.endAsyncSection(onDrawWaitingTraceTag, traceCookie);
- ((IKeyguardDrawnCallback) obj).onDrawn();
- } catch (RemoteException e) {
- Log.w(TAG, "Exception calling onDrawn():", e);
- }
- } else {
- Log.w(TAG, "KeyguardDrawnCallback#onDrawn() invoked > 1 times");
- }
- }
- });
+ mScreenLifecycle.dispatchScreenTurningOn();
Trace.endSection();
break;
case SCREEN_TURNED_ON:
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
index 4ae37c5..cbcede0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
@@ -21,14 +21,18 @@
import android.content.ContentValues
import android.content.Context
import android.content.UriMatcher
+import android.content.pm.PackageManager
import android.content.pm.ProviderInfo
import android.database.Cursor
import android.database.MatrixCursor
import android.net.Uri
+import android.os.Binder
+import android.os.Bundle
import android.util.Log
import com.android.systemui.SystemUIAppComponentFactoryBase
import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
+import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager
import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
import javax.inject.Inject
import kotlinx.coroutines.runBlocking
@@ -37,6 +41,7 @@
ContentProvider(), SystemUIAppComponentFactoryBase.ContextInitializer {
@Inject lateinit var interactor: KeyguardQuickAffordanceInteractor
+ @Inject lateinit var previewManager: KeyguardRemotePreviewManager
private lateinit var contextAvailableCallback: ContextAvailableCallback
@@ -149,6 +154,21 @@
return deleteSelection(uri, selectionArgs)
}
+ override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
+ return if (
+ requireContext()
+ .checkPermission(
+ android.Manifest.permission.BIND_WALLPAPER,
+ Binder.getCallingPid(),
+ Binder.getCallingUid(),
+ ) == PackageManager.PERMISSION_GRANTED
+ ) {
+ previewManager.preview(extras)
+ } else {
+ null
+ }
+ }
+
private fun insertSelection(values: ContentValues?): Uri? {
if (values == null) {
throw IllegalArgumentException("Cannot insert selection, no values passed in!")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index c332a0d..f4a1227 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -78,6 +78,7 @@
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
import com.android.internal.policy.IKeyguardStateCallback;
+import com.android.keyguard.mediator.ScreenOnCoordinator;
import com.android.systemui.SystemUIApplication;
import com.android.wm.shell.transition.ShellTransitions;
import com.android.wm.shell.transition.Transitions;
@@ -120,6 +121,7 @@
private final KeyguardViewMediator mKeyguardViewMediator;
private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
+ private final ScreenOnCoordinator mScreenOnCoordinator;
private final ShellTransitions mShellTransitions;
private static int newModeToLegacyMode(int newMode) {
@@ -283,10 +285,12 @@
@Inject
public KeyguardService(KeyguardViewMediator keyguardViewMediator,
KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher,
+ ScreenOnCoordinator screenOnCoordinator,
ShellTransitions shellTransitions) {
super();
mKeyguardViewMediator = keyguardViewMediator;
mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
+ mScreenOnCoordinator = screenOnCoordinator;
mShellTransitions = shellTransitions;
}
@@ -583,6 +587,31 @@
checkPermission();
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON,
callback);
+
+ final String onDrawWaitingTraceTag = "Waiting for KeyguardDrawnCallback#onDrawn";
+ final int traceCookie = System.identityHashCode(callback);
+ Trace.beginAsyncSection(onDrawWaitingTraceTag, traceCookie);
+
+ // Ensure the drawn callback is only ever called once
+ mScreenOnCoordinator.onScreenTurningOn(new Runnable() {
+ boolean mInvoked;
+ @Override
+ public void run() {
+ if (callback == null) return;
+ if (!mInvoked) {
+ mInvoked = true;
+ try {
+ Trace.endAsyncSection(onDrawWaitingTraceTag, traceCookie);
+ callback.onDrawn();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Exception calling onDrawn():", e);
+ }
+ } else {
+ Log.w(TAG, "KeyguardDrawnCallback#onDrawn() invoked > 1 times");
+ }
+ }
+ });
+
Trace.endSection();
}
@@ -591,6 +620,7 @@
Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
checkPermission();
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
+ mScreenOnCoordinator.onScreenTurnedOn();
Trace.endSection();
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 0c46b23..53070a0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -321,6 +321,7 @@
// and unlock the device as well as hiding the surface.
if (surfaceBehindAlpha == 0f) {
Log.d(TAG, "surfaceBehindAlphaAnimator#onAnimationEnd")
+ surfaceBehindRemoteAnimationTargets = null
keyguardViewMediator.get().finishSurfaceBehindRemoteAnimation(
false /* cancelled */)
} else {
@@ -825,13 +826,13 @@
// Make sure we made the surface behind fully visible, just in case. It should already be
// fully visible. The exit animation is finished, and we should not hold the leash anymore,
// so forcing it to 1f.
- surfaceBehindAlphaAnimator.cancel()
- surfaceBehindEntryAnimator.cancel()
surfaceBehindAlpha = 1f
setSurfaceBehindAppearAmount(1f)
+ surfaceBehindAlphaAnimator.cancel()
+ surfaceBehindEntryAnimator.cancel()
try {
launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
- } catch (e: RemoteException) {
+ } catch (e: RemoteException) {
Log.e(TAG, "Remote exception in notifyFinishedKeyguardExitAnimation", e)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d4b6386..ae714fb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -25,6 +25,7 @@
import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_OCCLUSION;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_UNLOCK_ANIMATION;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
@@ -32,6 +33,7 @@
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.keyguard.domain.interactor.DreamingTransitionInteractor.TO_LOCKSCREEN_DURATION_MS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -142,12 +144,12 @@
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.DeviceConfigProxy;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.Executor;
-import dagger.Lazy;
-
/**
* Mediates requests related to the keyguard. This includes queries about the
* state of the keyguard, power management events that effect whether the keyguard
@@ -722,7 +724,7 @@
@Override
public void keyguardDone(boolean strongAuth, int targetUserId) {
- if (targetUserId != mUserTracker.getUserId()) {
+ if (targetUserId != KeyguardUpdateMonitor.getCurrentUser()) {
return;
}
if (DEBUG) Log.d(TAG, "keyguardDone");
@@ -745,7 +747,7 @@
public void keyguardDonePending(boolean strongAuth, int targetUserId) {
Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardDonePending");
if (DEBUG) Log.d(TAG, "keyguardDonePending");
- if (targetUserId != mUserTracker.getUserId()) {
+ if (targetUserId != KeyguardUpdateMonitor.getCurrentUser()) {
Trace.endSection();
return;
}
@@ -821,6 +823,9 @@
} else if (trustAgentsEnabled
&& (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
+ } else if (trustAgentsEnabled
+ && (strongAuth & SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED;
} else if (any && ((strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0
|| mUpdateMonitor.isFingerprintLockedOut())) {
return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
@@ -1227,8 +1232,7 @@
mDreamOpenAnimationDuration = context.getResources().getInteger(
com.android.internal.R.integer.config_dreamOpenAnimationDuration);
- mDreamCloseAnimationDuration = context.getResources().getInteger(
- com.android.internal.R.integer.config_dreamCloseAnimationDuration);
+ mDreamCloseAnimationDuration = (int) TO_LOCKSCREEN_DURATION_MS;
}
public void userActivity() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
index 0a55294..6063ce2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
@@ -17,6 +17,7 @@
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
+import com.android.systemui.util.traceSection
import javax.inject.Inject
import javax.inject.Singleton
@@ -39,14 +40,22 @@
}
override fun onScreenTurnedOn() {
- listeners.forEach(ScreenListener::onScreenTurnedOn)
+ traceSection("$TRACE_TAG#onScreenTurnedOn") {
+ listeners.forEach(ScreenListener::onScreenTurnedOn)
+ }
}
override fun onScreenTurningOff() {
- listeners.forEach(ScreenListener::onScreenTurningOff)
+ traceSection("$TRACE_TAG#onScreenTurningOff") {
+ listeners.forEach(ScreenListener::onScreenTurningOff)
+ }
}
- override fun onScreenTurningOn(ignored: Runnable) {
- listeners.forEach(ScreenListener::onScreenTurningOn)
+ override fun onScreenTurningOn() {
+ traceSection("$TRACE_TAG#onScreenTurningOn") {
+ listeners.forEach(ScreenListener::onScreenTurningOn)
+ }
}
}
+
+private const val TRACE_TAG = "LifecycleScreenStatusProvider"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
index b348121..8535eda 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
@@ -18,8 +18,6 @@
import android.os.Trace;
-import androidx.annotation.NonNull;
-
import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager;
@@ -50,14 +48,9 @@
return mScreenState;
}
- /**
- * Dispatch screen turning on events to the registered observers
- *
- * @param onDrawn Invoke to notify the caller that the event has been processed
- */
- public void dispatchScreenTurningOn(@NonNull Runnable onDrawn) {
+ public void dispatchScreenTurningOn() {
setScreenState(SCREEN_TURNING_ON);
- dispatch(Observer::onScreenTurningOn, onDrawn);
+ dispatch(Observer::onScreenTurningOn);
}
public void dispatchScreenTurnedOn() {
@@ -87,12 +80,7 @@
}
public interface Observer {
- /**
- * Receive the screen turning on event
- *
- * @param onDrawn Invoke to notify the caller that the event has been processed
- */
- default void onScreenTurningOn(@NonNull Runnable onDrawn) {}
+ default void onScreenTurningOn() {}
default void onScreenTurnedOn() {}
default void onScreenTurningOff() {}
default void onScreenTurnedOff() {}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
index 73dbeab..ea5b4f4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
@@ -25,6 +25,7 @@
object BuiltInKeyguardQuickAffordanceKeys {
// Please keep alphabetical order of const names to simplify future maintenance.
const val CAMERA = "camera"
+ const val DO_NOT_DISTURB = "do_not_disturb"
const val FLASHLIGHT = "flashlight"
const val HOME_CONTROLS = "home"
const val QR_CODE_SCANNER = "qr_code_scanner"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
new file mode 100644
index 0000000..8efb366
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.android.systemui.keyguard.data.quickaffordance
+
+import android.content.Context
+import android.net.Uri
+import android.provider.Settings
+import android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+import android.provider.Settings.Global.ZEN_MODE_OFF
+import android.provider.Settings.Secure.ZEN_DURATION_FOREVER
+import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
+import android.service.notification.ZenModeConfig
+import com.android.settingslib.notification.EnableZenModeDialog
+import com.android.settingslib.notification.ZenModeDialogMetricsLogger
+import com.android.systemui.R
+import com.android.systemui.animation.Expandable
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.policy.ZenModeController
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.onStart
+import javax.inject.Inject
+
+@SysUISingleton
+class DoNotDisturbQuickAffordanceConfig constructor(
+ private val context: Context,
+ private val controller: ZenModeController,
+ private val secureSettings: SecureSettings,
+ private val userTracker: UserTracker,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+ private val testConditionId: Uri?,
+ testDialog: EnableZenModeDialog?,
+): KeyguardQuickAffordanceConfig {
+
+ @Inject
+ constructor(
+ context: Context,
+ controller: ZenModeController,
+ secureSettings: SecureSettings,
+ userTracker: UserTracker,
+ @Background backgroundDispatcher: CoroutineDispatcher,
+ ) : this(context, controller, secureSettings, userTracker, backgroundDispatcher, null, null)
+
+ private var dndMode: Int = 0
+ private var isAvailable = false
+ private var settingsValue: Int = 0
+
+ private val conditionUri: Uri
+ get() =
+ testConditionId ?: ZenModeConfig.toTimeCondition(
+ context,
+ settingsValue,
+ userTracker.userId,
+ true, /* shortVersion */
+ ).id
+
+ private val dialog: EnableZenModeDialog by lazy {
+ testDialog ?: EnableZenModeDialog(
+ context,
+ R.style.Theme_SystemUI_Dialog,
+ true, /* cancelIsNeutral */
+ ZenModeDialogMetricsLogger(context),
+ )
+ }
+
+ override val key: String = BuiltInKeyguardQuickAffordanceKeys.DO_NOT_DISTURB
+
+ override val pickerName: String = context.getString(R.string.quick_settings_dnd_label)
+
+ override val pickerIconResourceId: Int = R.drawable.ic_do_not_disturb
+
+ override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> = combine(
+ conflatedCallbackFlow {
+ val callback = object: ZenModeController.Callback {
+ override fun onZenChanged(zen: Int) {
+ dndMode = zen
+ trySendWithFailureLogging(updateState(), TAG)
+ }
+
+ override fun onZenAvailableChanged(available: Boolean) {
+ isAvailable = available
+ trySendWithFailureLogging(updateState(), TAG)
+ }
+ }
+
+ dndMode = controller.zen
+ isAvailable = controller.isZenAvailable
+ trySendWithFailureLogging(updateState(), TAG)
+
+ controller.addCallback(callback)
+
+ awaitClose { controller.removeCallback(callback) }
+ },
+ secureSettings
+ .observerFlow(Settings.Secure.ZEN_DURATION)
+ .onStart { emit(Unit) }
+ .map { secureSettings.getInt(Settings.Secure.ZEN_DURATION, ZEN_MODE_OFF) }
+ .flowOn(backgroundDispatcher)
+ .distinctUntilChanged()
+ .onEach { settingsValue = it }
+ ) { callbackFlowValue, _ -> callbackFlowValue }
+
+ override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
+ return if (controller.isZenAvailable) {
+ KeyguardQuickAffordanceConfig.PickerScreenState.Default
+ } else {
+ KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+ }
+ }
+
+ override fun onTriggered(expandable: Expandable?):
+ KeyguardQuickAffordanceConfig.OnTriggeredResult {
+ return when {
+ !isAvailable ->
+ KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
+ dndMode != ZEN_MODE_OFF -> {
+ controller.setZen(ZEN_MODE_OFF, null, TAG)
+ KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
+ }
+ settingsValue == ZEN_DURATION_PROMPT ->
+ KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog(
+ dialog.createDialog(),
+ expandable
+ )
+ settingsValue == ZEN_DURATION_FOREVER -> {
+ controller.setZen(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, TAG)
+ KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
+ }
+ else -> {
+ controller.setZen(ZEN_MODE_IMPORTANT_INTERRUPTIONS, conditionUri, TAG)
+ KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
+ }
+ }
+ }
+
+ private fun updateState(): KeyguardQuickAffordanceConfig.LockScreenState {
+ return if (!isAvailable) {
+ KeyguardQuickAffordanceConfig.LockScreenState.Hidden
+ } else if (dndMode == ZEN_MODE_OFF) {
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ Icon.Resource(
+ R.drawable.qs_dnd_icon_off,
+ ContentDescription.Resource(R.string.dnd_is_off),
+ ),
+ ActivationState.Inactive,
+ )
+ } else {
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ Icon.Resource(
+ R.drawable.qs_dnd_icon_on,
+ ContentDescription.Resource(R.string.dnd_is_on),
+ ),
+ ActivationState.Active,
+ )
+ }
+ }
+
+ companion object {
+ const val TAG = "DoNotDisturbQuickAffordanceConfig"
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
index 072cfb1..71d01eb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
@@ -33,6 +33,7 @@
@Provides
@ElementsIntoSet
fun quickAffordanceConfigs(
+ doNotDisturb: DoNotDisturbQuickAffordanceConfig,
flashlight: FlashlightQuickAffordanceConfig,
home: HomeControlsKeyguardQuickAffordanceConfig,
quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
@@ -41,6 +42,7 @@
): Set<KeyguardQuickAffordanceConfig> {
return setOf(
camera,
+ doNotDisturb,
flashlight,
home,
quickAccessWallet,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
index 98b1a73..02ebcd3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.data.quickaffordance
+import android.app.AlertDialog
import android.content.Intent
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
@@ -141,6 +142,16 @@
val intent: Intent,
val canShowWhileLocked: Boolean,
) : OnTriggeredResult()
+
+ /**
+ * Returning this as a result from the [onTriggered] method means that the implementation
+ * has _not_ taken care of the action and the system should show a Dialog using the
+ * given [AlertDialog] and [Expandable].
+ */
+ data class ShowDialog(
+ val dialog: AlertDialog,
+ val expandable: Expandable?,
+ ) : OnTriggeredResult()
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index 148792b..9a0fbbf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -29,6 +29,8 @@
import com.android.systemui.doze.DozeMachine
import com.android.systemui.doze.DozeTransitionCallback
import com.android.systemui.doze.DozeTransitionListener
+import com.android.systemui.dreams.DreamCallbackController
+import com.android.systemui.dreams.DreamCallbackController.DreamCallback
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
@@ -47,6 +49,7 @@
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.merge
/** Defines interface for classes that encapsulate application state for the keyguard. */
interface KeyguardRepository {
@@ -176,6 +179,7 @@
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val dozeTransitionListener: DozeTransitionListener,
private val authController: AuthController,
+ private val dreamCallbackController: DreamCallbackController,
) : KeyguardRepository {
private val _animateBottomAreaDozingTransitions = MutableStateFlow(false)
override val animateBottomAreaDozingTransitions =
@@ -276,22 +280,35 @@
.distinctUntilChanged()
override val isDreaming: Flow<Boolean> =
- conflatedCallbackFlow {
- val callback =
- object : KeyguardUpdateMonitorCallback() {
- override fun onDreamingStateChanged(isDreaming: Boolean) {
- trySendWithFailureLogging(isDreaming, TAG, "updated isDreaming")
+ merge(
+ conflatedCallbackFlow {
+ val callback =
+ object : KeyguardUpdateMonitorCallback() {
+ override fun onDreamingStateChanged(isDreaming: Boolean) {
+ trySendWithFailureLogging(isDreaming, TAG, "updated isDreaming")
+ }
}
- }
- keyguardUpdateMonitor.registerCallback(callback)
- trySendWithFailureLogging(
- keyguardUpdateMonitor.isDreaming,
- TAG,
- "initial isDreaming",
- )
+ keyguardUpdateMonitor.registerCallback(callback)
+ trySendWithFailureLogging(
+ keyguardUpdateMonitor.isDreaming,
+ TAG,
+ "initial isDreaming",
+ )
- awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
- }
+ awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
+ },
+ conflatedCallbackFlow {
+ val callback =
+ object : DreamCallback {
+ override fun onWakeUp() {
+ trySendWithFailureLogging(false, TAG, "updated isDreaming")
+ }
+ }
+ dreamCallbackController.addCallback(callback)
+
+ awaitClose { dreamCallbackController.removeCallback(callback) }
+ }
+ )
.distinctUntilChanged()
override val linearDozeAmount: Flow<Float> = conflatedCallbackFlow {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
index 5bb586e..d72d7183b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
@@ -66,8 +66,8 @@
}
/**
- * Begin a transition from one state to another. Will not start if another transition is in
- * progress.
+ * Begin a transition from one state to another. Transitions are interruptible, and will issue a
+ * [TransitionStep] with state = [TransitionState.CANCELED] before beginning the next one.
*/
fun startTransition(info: TransitionInfo): UUID?
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DreamingTransitionInteractor.kt
index b73ce9e..4d60579 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DreamingTransitionInteractor.kt
@@ -28,6 +28,8 @@
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
@@ -110,7 +112,7 @@
name,
KeyguardState.DREAMING,
KeyguardState.LOCKSCREEN,
- getAnimator(),
+ getAnimator(TO_LOCKSCREEN_DURATION),
)
)
}
@@ -167,14 +169,16 @@
}
}
- private fun getAnimator(): ValueAnimator {
+ private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
return ValueAnimator().apply {
setInterpolator(Interpolators.LINEAR)
- setDuration(TRANSITION_DURATION_MS)
+ setDuration(duration.inWholeMilliseconds)
}
}
companion object {
- private const val TRANSITION_DURATION_MS = 500L
+ private val DEFAULT_DURATION = 500.milliseconds
+ val TO_LOCKSCREEN_DURATION = 1183.milliseconds
+ @JvmField val TO_LOCKSCREEN_DURATION_MS = TO_LOCKSCREEN_DURATION.inWholeMilliseconds
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index 748c6e8..9772cb9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -17,9 +17,11 @@
package com.android.systemui.keyguard.domain.interactor
+import android.app.AlertDialog
import android.content.Intent
import android.util.Log
import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
@@ -34,8 +36,8 @@
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserTracker
-import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract
+import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.policy.KeyguardStateController
import dagger.Lazy
import javax.inject.Inject
@@ -58,16 +60,25 @@
private val activityStarter: ActivityStarter,
private val featureFlags: FeatureFlags,
private val repository: Lazy<KeyguardQuickAffordanceRepository>,
+ private val launchAnimator: DialogLaunchAnimator,
) {
private val isUsingRepository: Boolean
get() = featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)
+ /**
+ * Whether the UI should use the long press gesture to activate quick affordances.
+ *
+ * If `false`, the UI goes back to using single taps.
+ */
+ val useLongPress: Boolean
+ get() = featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)
+
/** Returns an observable for the quick affordance at the given position. */
fun quickAffordance(
position: KeyguardQuickAffordancePosition
): Flow<KeyguardQuickAffordanceModel> {
return combine(
- quickAffordanceInternal(position),
+ quickAffordanceAlwaysVisible(position),
keyguardInteractor.isDozing,
keyguardInteractor.isKeyguardShowing,
) { affordance, isDozing, isKeyguardShowing ->
@@ -80,6 +91,19 @@
}
/**
+ * Returns an observable for the quick affordance at the given position but always visible,
+ * regardless of lock screen state.
+ *
+ * This is useful for experiences like the lock screen preview mode, where the affordances must
+ * always be visible.
+ */
+ fun quickAffordanceAlwaysVisible(
+ position: KeyguardQuickAffordancePosition,
+ ): Flow<KeyguardQuickAffordanceModel> {
+ return quickAffordanceInternal(position)
+ }
+
+ /**
* Notifies that a quick affordance has been "triggered" (clicked) by the user.
*
* @param configKey The configuration key corresponding to the [KeyguardQuickAffordanceModel] of
@@ -111,6 +135,11 @@
expandable = expandable,
)
is KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled -> Unit
+ is KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog ->
+ showDialog(
+ result.dialog,
+ result.expandable,
+ )
}
}
@@ -259,6 +288,16 @@
}
}
+ private fun showDialog(dialog: AlertDialog, expandable: Expandable?) {
+ expandable?.dialogLaunchController()?.let { controller ->
+ SystemUIDialog.applyFlags(dialog)
+ SystemUIDialog.setShowForAllUsers(dialog, true)
+ SystemUIDialog.registerDismissListener(dialog)
+ SystemUIDialog.setDialogSize(dialog)
+ launchAnimator.show(dialog, controller)
+ }
+ }
+
private fun launchQuickAffordance(
intent: Intent,
canShowWhileLocked: Boolean,
@@ -290,15 +329,6 @@
}
}
- private fun KeyguardQuickAffordancePosition.toSlotId(): String {
- return when (this) {
- KeyguardQuickAffordancePosition.BOTTOM_START ->
- KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
- KeyguardQuickAffordancePosition.BOTTOM_END ->
- KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END
- }
- }
-
private fun String.encode(slotId: String): String {
return "$slotId$DELIMITER$this"
}
@@ -322,9 +352,17 @@
fun getPickerFlags(): List<KeyguardPickerFlag> {
return listOf(
KeyguardPickerFlag(
- name = KeyguardQuickAffordanceProviderContract.FlagsTable.FLAG_NAME_FEATURE_ENABLED,
+ name = Contract.FlagsTable.FLAG_NAME_REVAMPED_WALLPAPER_UI,
+ value = featureFlags.isEnabled(Flags.REVAMPED_WALLPAPER_UI),
+ ),
+ KeyguardPickerFlag(
+ name = Contract.FlagsTable.FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
value = featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES),
- )
+ ),
+ KeyguardPickerFlag(
+ name = Contract.FlagsTable.FLAG_NAME_CUSTOM_CLOCKS_ENABLED,
+ value = featureFlags.isEnabled(Flags.LOCKSCREEN_CUSTOM_CLOCKS),
+ ),
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 54a4f49..3b9d6f5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -19,12 +19,15 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.AnimationParams
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
+import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import javax.inject.Inject
+import kotlin.time.Duration
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
@@ -43,6 +46,10 @@
/** LOCKSCREEN->AOD transition information. */
val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
+ /** DREAMING->LOCKSCREEN transition information. */
+ val dreamingToLockscreenTransition: Flow<TransitionStep> =
+ repository.transition(DREAMING, LOCKSCREEN)
+
/** (any)->AOD transition information */
val anyStateToAodTransition: Flow<TransitionStep> =
repository.transitions.filter { step -> step.to == KeyguardState.AOD }
@@ -72,4 +79,21 @@
/* The last completed [KeyguardState] transition */
val finishedKeyguardState: Flow<KeyguardState> =
finishedKeyguardTransitionStep.map { step -> step.to }
+
+ /**
+ * Transitions will occur over a [totalDuration] with [TransitionStep]s being emitted in the
+ * range of [0, 1]. View animations should begin and end within a subset of this range. This
+ * function maps the [startTime] and [duration] into [0, 1], when this subset is valid.
+ */
+ fun transitionStepAnimation(
+ flow: Flow<TransitionStep>,
+ params: AnimationParams,
+ totalDuration: Duration,
+ ): Flow<Float> {
+ val start = (params.startTime / totalDuration).toFloat()
+ val chunks = (totalDuration / params.duration).toFloat()
+ return flow
+ .map { step -> (step.value - start) * chunks }
+ .filter { value -> value >= 0f && value <= 1f }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenBouncerTransitionInteractor.kt
index 3218f96..5cb7d70 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenBouncerTransitionInteractor.kt
@@ -22,7 +22,7 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE_LOCKED
+import com.android.systemui.keyguard.shared.model.StatusBarState.KEYGUARD
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.WakefulnessState
@@ -50,27 +50,22 @@
override fun start() {
listenForDraggingUpToBouncer()
- listenForBouncerHiding()
+ listenForBouncer()
}
- private fun listenForBouncerHiding() {
+ private fun listenForBouncer() {
scope.launch {
keyguardInteractor.isBouncerShowing
.sample(
combine(
keyguardInteractor.wakefulnessModel,
keyguardTransitionInteractor.startedKeyguardTransitionStep,
- ) { wakefulnessModel, transitionStep ->
- Pair(wakefulnessModel, transitionStep)
- }
- ) { bouncerShowing, wakefulnessAndTransition ->
- Triple(
- bouncerShowing,
- wakefulnessAndTransition.first,
- wakefulnessAndTransition.second
- )
- }
- .collect { (isBouncerShowing, wakefulnessState, lastStartedTransitionStep) ->
+ ::Pair
+ ),
+ ::toTriple
+ )
+ .collect { triple ->
+ val (isBouncerShowing, wakefulnessState, lastStartedTransitionStep) = triple
if (
!isBouncerShowing && lastStartedTransitionStep.to == KeyguardState.BOUNCER
) {
@@ -91,7 +86,19 @@
animator = getAnimator(),
)
)
+ } else if (
+ isBouncerShowing && lastStartedTransitionStep.to == KeyguardState.LOCKSCREEN
+ ) {
+ keyguardTransitionRepository.startTransition(
+ TransitionInfo(
+ ownerName = name,
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.BOUNCER,
+ animator = getAnimator(),
+ )
+ )
}
+ Unit
}
}
}
@@ -104,24 +111,20 @@
combine(
keyguardTransitionInteractor.finishedKeyguardState,
keyguardInteractor.statusBarState,
- ) { finishedKeyguardState, statusBarState ->
- Pair(finishedKeyguardState, statusBarState)
- }
- ) { shadeModel, keyguardStateAndStatusBarState ->
- Triple(
- shadeModel,
- keyguardStateAndStatusBarState.first,
- keyguardStateAndStatusBarState.second
- )
- }
- .collect { (shadeModel, keyguardState, statusBarState) ->
+ ::Pair
+ ),
+ ::toTriple
+ )
+ .collect { triple ->
+ val (shadeModel, keyguardState, statusBarState) = triple
+
val id = transitionId
if (id != null) {
// An existing `id` means a transition is started, and calls to
// `updateTransition` will control it until FINISHED
keyguardTransitionRepository.updateTransition(
id,
- shadeModel.expansionAmount,
+ 1f - shadeModel.expansionAmount,
if (
shadeModel.expansionAmount == 0f || shadeModel.expansionAmount == 1f
) {
@@ -137,7 +140,7 @@
if (
keyguardState == KeyguardState.LOCKSCREEN &&
shadeModel.isUserDragging &&
- statusBarState != SHADE_LOCKED
+ statusBarState == KEYGUARD
) {
transitionId =
keyguardTransitionRepository.startTransition(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
index 2cf5fb9..2a3a33e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
@@ -77,7 +77,6 @@
/** Runnable to show the primary bouncer. */
val showRunnable = Runnable {
- repository.setPrimaryVisible(true)
repository.setPrimaryShow(
KeyguardBouncerModel(
promptReason = repository.bouncerPromptReason ?: 0,
@@ -86,6 +85,7 @@
)
)
repository.setPrimaryShowingSoon(false)
+ repository.setPrimaryVisible(true)
primaryBouncerCallbackInteractor.dispatchVisibilityChanged(View.VISIBLE)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AnimationParams.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AnimationParams.kt
new file mode 100644
index 0000000..67733e9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AnimationParams.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.systemui.keyguard.shared.model
+
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
+
+/** Animation parameters */
+data class AnimationParams(
+ val startTime: Duration = 0.milliseconds,
+ val duration: Duration,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt
index a18b036..2581b59 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt
@@ -16,8 +16,17 @@
package com.android.systemui.keyguard.shared.quickaffordance
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+
/** Enumerates all possible positions for quick affordances that can appear on the lock-screen. */
enum class KeyguardQuickAffordancePosition {
BOTTOM_START,
- BOTTOM_END,
+ BOTTOM_END;
+
+ fun toSlotId(): String {
+ return when (this) {
+ BOTTOM_START -> KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
+ BOTTOM_END -> KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index cbe512f..ae8edfe 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -16,14 +16,19 @@
package com.android.systemui.keyguard.ui.binder
+import android.annotation.SuppressLint
import android.graphics.drawable.Animatable2
import android.util.Size
import android.util.TypedValue
+import android.view.MotionEvent
import android.view.View
+import android.view.ViewConfiguration
import android.view.ViewGroup
import android.view.ViewPropertyAnimator
import android.widget.ImageView
import android.widget.TextView
+import androidx.core.animation.CycleInterpolator
+import androidx.core.animation.ObjectAnimator
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.lifecycle.Lifecycle
@@ -38,8 +43,10 @@
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.FalsingManager
+import kotlin.math.pow
+import kotlin.math.sqrt
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
@@ -52,6 +59,7 @@
* view-binding, binding each view only once. It is okay and expected for the same instance of the
* view-model to be reused for multiple view/view-binder bindings.
*/
+@OptIn(ExperimentalCoroutinesApi::class)
object KeyguardBottomAreaViewBinder {
private const val EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS = 250L
@@ -84,7 +92,8 @@
fun bind(
view: ViewGroup,
viewModel: KeyguardBottomAreaViewModel,
- falsingManager: FalsingManager,
+ falsingManager: FalsingManager?,
+ messageDisplayer: (Int) -> Unit,
): Binding {
val indicationArea: View = view.requireViewById(R.id.keyguard_indication_area)
val ambientIndicationArea: View? = view.findViewById(R.id.ambient_indication_container)
@@ -108,6 +117,7 @@
view = startButton,
viewModel = buttonModel,
falsingManager = falsingManager,
+ messageDisplayer = messageDisplayer,
)
}
}
@@ -118,6 +128,7 @@
view = endButton,
viewModel = buttonModel,
falsingManager = falsingManager,
+ messageDisplayer = messageDisplayer,
)
}
}
@@ -222,10 +233,12 @@
}
}
+ @SuppressLint("ClickableViewAccessibility")
private fun updateButton(
view: ImageView,
viewModel: KeyguardQuickAffordanceViewModel,
- falsingManager: FalsingManager,
+ falsingManager: FalsingManager?,
+ messageDisplayer: (Int) -> Unit,
) {
if (!viewModel.isVisible) {
view.isVisible = false
@@ -281,21 +294,126 @@
},
)
)
+
view.backgroundTintList =
- Utils.getColorAttr(
- view.context,
- if (viewModel.isActivated) {
- com.android.internal.R.attr.colorAccentPrimary
- } else {
- com.android.internal.R.attr.colorSurface
- }
- )
+ if (!viewModel.isSelected) {
+ Utils.getColorAttr(
+ view.context,
+ if (viewModel.isActivated) {
+ com.android.internal.R.attr.colorAccentPrimary
+ } else {
+ com.android.internal.R.attr.colorSurface
+ }
+ )
+ } else {
+ null
+ }
view.isClickable = viewModel.isClickable
if (viewModel.isClickable) {
- view.setOnClickListener(OnClickListener(viewModel, falsingManager))
+ if (viewModel.useLongPress) {
+ view.setOnTouchListener(OnTouchListener(view, viewModel, messageDisplayer))
+ } else {
+ view.setOnClickListener(OnClickListener(viewModel, checkNotNull(falsingManager)))
+ }
} else {
view.setOnClickListener(null)
+ view.setOnTouchListener(null)
+ }
+
+ view.isSelected = viewModel.isSelected
+ }
+
+ private class OnTouchListener(
+ private val view: View,
+ private val viewModel: KeyguardQuickAffordanceViewModel,
+ private val messageDisplayer: (Int) -> Unit,
+ ) : View.OnTouchListener {
+
+ private val longPressDurationMs = ViewConfiguration.getLongPressTimeout().toLong()
+ private var longPressAnimator: ViewPropertyAnimator? = null
+ private var downTimestamp = 0L
+
+ @SuppressLint("ClickableViewAccessibility")
+ override fun onTouch(v: View?, event: MotionEvent?): Boolean {
+ return when (event?.actionMasked) {
+ MotionEvent.ACTION_DOWN ->
+ if (viewModel.configKey != null) {
+ downTimestamp = System.currentTimeMillis()
+ longPressAnimator =
+ view
+ .animate()
+ .scaleX(PRESSED_SCALE)
+ .scaleY(PRESSED_SCALE)
+ .setDuration(longPressDurationMs)
+ .withEndAction {
+ view.setOnClickListener {
+ viewModel.onClicked(
+ KeyguardQuickAffordanceViewModel.OnClickedParameters(
+ configKey = viewModel.configKey,
+ expandable = Expandable.fromView(view),
+ )
+ )
+ }
+ view.performClick()
+ view.setOnClickListener(null)
+ }
+ true
+ } else {
+ false
+ }
+ MotionEvent.ACTION_MOVE -> {
+ if (event.historySize > 0) {
+ val distance =
+ sqrt(
+ (event.y - event.getHistoricalY(0)).pow(2) +
+ (event.x - event.getHistoricalX(0)).pow(2)
+ )
+ if (distance > ViewConfiguration.getTouchSlop()) {
+ cancel()
+ }
+ }
+ true
+ }
+ MotionEvent.ACTION_UP -> {
+ if (System.currentTimeMillis() - downTimestamp < longPressDurationMs) {
+ messageDisplayer.invoke(R.string.keyguard_affordance_press_too_short)
+ val shakeAnimator =
+ ObjectAnimator.ofFloat(
+ view,
+ "translationX",
+ 0f,
+ view.context.resources
+ .getDimensionPixelSize(
+ R.dimen.keyguard_affordance_shake_amplitude
+ )
+ .toFloat(),
+ 0f,
+ )
+ shakeAnimator.duration = 300
+ shakeAnimator.interpolator = CycleInterpolator(5f)
+ shakeAnimator.start()
+ }
+ cancel()
+ true
+ }
+ MotionEvent.ACTION_CANCEL -> {
+ cancel()
+ true
+ }
+ else -> false
+ }
+ }
+
+ private fun cancel() {
+ downTimestamp = 0L
+ longPressAnimator?.cancel()
+ longPressAnimator = null
+ view.animate().scaleX(1f).scaleY(1f)
+ }
+
+ companion object {
+ private const val PRESSED_SCALE = 1.5f
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
new file mode 100644
index 0000000..a5ae8ba5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.preview
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.hardware.display.DisplayManager
+import android.os.Bundle
+import android.os.IBinder
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.SurfaceControlViewHost
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowManager
+import android.widget.FrameLayout
+import com.android.keyguard.ClockEventController
+import com.android.keyguard.KeyguardClockSwitch
+import com.android.systemui.R
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel
+import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardQuickAffordancePreviewConstants
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.runBlocking
+
+/** Renders the preview of the lock screen. */
+class KeyguardPreviewRenderer
+@AssistedInject
+constructor(
+ @Application private val context: Context,
+ @Main private val mainDispatcher: CoroutineDispatcher,
+ private val bottomAreaViewModel: KeyguardBottomAreaViewModel,
+ displayManager: DisplayManager,
+ private val windowManager: WindowManager,
+ private val clockController: ClockEventController,
+ private val clockRegistry: ClockRegistry,
+ private val broadcastDispatcher: BroadcastDispatcher,
+ @Assisted bundle: Bundle,
+) {
+
+ val hostToken: IBinder? = bundle.getBinder(KEY_HOST_TOKEN)
+ private val width: Int = bundle.getInt(KEY_VIEW_WIDTH)
+ private val height: Int = bundle.getInt(KEY_VIEW_HEIGHT)
+
+ private var host: SurfaceControlViewHost
+
+ val surfacePackage: SurfaceControlViewHost.SurfacePackage
+ get() = host.surfacePackage
+
+ private var clockView: View? = null
+
+ private val disposables = mutableSetOf<DisposableHandle>()
+ private var isDestroyed = false
+
+ init {
+ bottomAreaViewModel.enablePreviewMode(
+ initiallySelectedSlotId =
+ bundle.getString(
+ KeyguardQuickAffordancePreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID,
+ ),
+ )
+ runBlocking(mainDispatcher) {
+ host =
+ SurfaceControlViewHost(
+ context,
+ displayManager.getDisplay(bundle.getInt(KEY_DISPLAY_ID)),
+ hostToken,
+ )
+ disposables.add(DisposableHandle { host.release() })
+ }
+ }
+
+ fun render() {
+ runBlocking(mainDispatcher) {
+ val rootView = FrameLayout(context)
+
+ setUpBottomArea(rootView)
+ setUpClock(rootView)
+
+ rootView.measure(
+ View.MeasureSpec.makeMeasureSpec(
+ windowManager.currentWindowMetrics.bounds.width(),
+ View.MeasureSpec.EXACTLY
+ ),
+ View.MeasureSpec.makeMeasureSpec(
+ windowManager.currentWindowMetrics.bounds.height(),
+ View.MeasureSpec.EXACTLY
+ ),
+ )
+ rootView.layout(0, 0, rootView.measuredWidth, rootView.measuredHeight)
+
+ // This aspect scales the view to fit in the surface and centers it
+ val scale: Float =
+ (width / rootView.measuredWidth.toFloat()).coerceAtMost(
+ height / rootView.measuredHeight.toFloat()
+ )
+
+ rootView.scaleX = scale
+ rootView.scaleY = scale
+ rootView.pivotX = 0f
+ rootView.pivotY = 0f
+ rootView.translationX = (width - scale * rootView.width) / 2
+ rootView.translationY = (height - scale * rootView.height) / 2
+
+ host.setView(rootView, rootView.measuredWidth, rootView.measuredHeight)
+ }
+ }
+
+ fun onSlotSelected(slotId: String) {
+ bottomAreaViewModel.onPreviewSlotSelected(slotId = slotId)
+ }
+
+ fun destroy() {
+ isDestroyed = true
+ disposables.forEach { it.dispose() }
+ }
+
+ private fun setUpBottomArea(parentView: ViewGroup) {
+ val bottomAreaView =
+ LayoutInflater.from(context)
+ .inflate(
+ R.layout.keyguard_bottom_area,
+ parentView,
+ false,
+ ) as KeyguardBottomAreaView
+ bottomAreaView.init(
+ viewModel = bottomAreaViewModel,
+ )
+ parentView.addView(
+ bottomAreaView,
+ FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT,
+ Gravity.BOTTOM,
+ ),
+ )
+ }
+
+ private fun setUpClock(parentView: ViewGroup) {
+ val clockChangeListener = ClockRegistry.ClockChangeListener { onClockChanged(parentView) }
+ clockRegistry.registerClockChangeListener(clockChangeListener)
+ disposables.add(
+ DisposableHandle { clockRegistry.unregisterClockChangeListener(clockChangeListener) }
+ )
+
+ clockController.registerListeners(parentView)
+ disposables.add(DisposableHandle { clockController.unregisterListeners() })
+
+ val receiver =
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ clockController.clock?.events?.onTimeTick()
+ }
+ }
+ broadcastDispatcher.registerReceiver(
+ receiver,
+ IntentFilter().apply {
+ addAction(Intent.ACTION_TIME_TICK)
+ addAction(Intent.ACTION_TIME_CHANGED)
+ },
+ )
+ disposables.add(DisposableHandle { broadcastDispatcher.unregisterReceiver(receiver) })
+
+ onClockChanged(parentView)
+ }
+
+ private fun onClockChanged(parentView: ViewGroup) {
+ clockController.clock = clockRegistry.createCurrentClock()
+ clockController.clock
+ ?.largeClock
+ ?.events
+ ?.onTargetRegionChanged(KeyguardClockSwitch.getLargeClockRegion(parentView))
+ clockView?.let { parentView.removeView(it) }
+ clockView = clockController.clock?.largeClock?.view?.apply { parentView.addView(this) }
+ }
+
+ companion object {
+ private const val KEY_HOST_TOKEN = "host_token"
+ private const val KEY_VIEW_WIDTH = "width"
+ private const val KEY_VIEW_HEIGHT = "height"
+ private const val KEY_DISPLAY_ID = "display_id"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRendererFactory.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRendererFactory.kt
new file mode 100644
index 0000000..be1d3a1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRendererFactory.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.preview
+
+import android.os.Bundle
+import dagger.assisted.AssistedFactory
+
+@AssistedFactory
+interface KeyguardPreviewRendererFactory {
+ fun create(bundle: Bundle): KeyguardPreviewRenderer
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
new file mode 100644
index 0000000..50722d5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.preview
+
+import android.os.Bundle
+import android.os.Handler
+import android.os.IBinder
+import android.os.Message
+import android.os.Messenger
+import android.util.ArrayMap
+import android.util.Log
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardQuickAffordancePreviewConstants
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.runBlocking
+
+@SysUISingleton
+class KeyguardRemotePreviewManager
+@Inject
+constructor(
+ private val previewRendererFactory: KeyguardPreviewRendererFactory,
+ @Main private val mainDispatcher: CoroutineDispatcher,
+ @Background private val backgroundHandler: Handler,
+) {
+ private val activePreviews: ArrayMap<IBinder, PreviewLifecycleObserver> =
+ ArrayMap<IBinder, PreviewLifecycleObserver>()
+
+ fun preview(request: Bundle?): Bundle? {
+ if (request == null) {
+ return null
+ }
+
+ var observer: PreviewLifecycleObserver? = null
+ return try {
+ val renderer = previewRendererFactory.create(request)
+
+ // Destroy any previous renderer associated with this token.
+ activePreviews[renderer.hostToken]?.let { destroyObserver(it) }
+ observer = PreviewLifecycleObserver(renderer, mainDispatcher, ::destroyObserver)
+ activePreviews[renderer.hostToken] = observer
+ renderer.render()
+ renderer.hostToken?.linkToDeath(observer, 0)
+ val result = Bundle()
+ result.putParcelable(
+ KEY_PREVIEW_SURFACE_PACKAGE,
+ renderer.surfacePackage,
+ )
+ val messenger =
+ Messenger(
+ Handler(
+ backgroundHandler.looper,
+ observer,
+ )
+ )
+ val msg = Message.obtain()
+ msg.replyTo = messenger
+ result.putParcelable(KEY_PREVIEW_CALLBACK, msg)
+ result
+ } catch (e: Exception) {
+ Log.e(TAG, "Unable to generate preview", e)
+ observer?.let { destroyObserver(it) }
+ null
+ }
+ }
+
+ private fun destroyObserver(observer: PreviewLifecycleObserver) {
+ observer.onDestroy()?.let { hostToken ->
+ if (activePreviews[hostToken] === observer) {
+ activePreviews.remove(hostToken)
+ }
+ }
+ }
+
+ private class PreviewLifecycleObserver(
+ private val renderer: KeyguardPreviewRenderer,
+ private val mainDispatcher: CoroutineDispatcher,
+ private val requestDestruction: (PreviewLifecycleObserver) -> Unit,
+ ) : Handler.Callback, IBinder.DeathRecipient {
+
+ private var isDestroyed = false
+
+ override fun handleMessage(message: Message): Boolean {
+ when (message.what) {
+ KeyguardQuickAffordancePreviewConstants.MESSAGE_ID_SLOT_SELECTED -> {
+ message.data
+ .getString(
+ KeyguardQuickAffordancePreviewConstants.KEY_SLOT_ID,
+ )
+ ?.let { slotId -> renderer.onSlotSelected(slotId = slotId) }
+ }
+ else -> requestDestruction(this)
+ }
+
+ return true
+ }
+
+ override fun binderDied() {
+ requestDestruction(this)
+ }
+
+ fun onDestroy(): IBinder? {
+ if (isDestroyed) {
+ return null
+ }
+
+ isDestroyed = true
+ val hostToken = renderer.hostToken
+ hostToken?.unlinkToDeath(this, 0)
+ runBlocking(mainDispatcher) { renderer.destroy() }
+ return hostToken
+ }
+ }
+
+ companion object {
+ private const val TAG = "KeyguardRemotePreviewManager"
+ @VisibleForTesting const val KEY_PREVIEW_SURFACE_PACKAGE = "surface_package"
+ @VisibleForTesting const val KEY_PREVIEW_CALLBACK = "callback"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
new file mode 100644
index 0000000..9b36e8c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.DreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+
+/**
+ * Breaks down DREAMING->LOCKSCREEN transition into discrete steps for corresponding views to
+ * consume.
+ */
+@SysUISingleton
+class DreamingToLockscreenTransitionViewModel
+@Inject
+constructor(
+ private val interactor: KeyguardTransitionInteractor,
+) {
+
+ /** Dream overlay y-translation on exit */
+ fun dreamOverlayTranslationY(translatePx: Int): Flow<Float> {
+ return flowForAnimation(DREAM_OVERLAY_TRANSLATION_Y).map { value ->
+ EMPHASIZED_ACCELERATE.getInterpolation(value) * translatePx
+ }
+ }
+ /** Dream overlay views alpha - fade out */
+ val dreamOverlayAlpha: Flow<Float> = flowForAnimation(DREAM_OVERLAY_ALPHA).map { 1f - it }
+
+ /** Dream background alpha - fade out */
+ val dreamBackgroundAlpha: Flow<Float> = flowForAnimation(DREAM_BACKGROUND_ALPHA).map { 1f - it }
+
+ /** Lockscreen views y-translation */
+ fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
+ return flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { it * translatePx }
+ }
+
+ /** Lockscreen views alpha */
+ val lockscreenAlpha: Flow<Float> = flowForAnimation(LOCKSCREEN_ALPHA)
+
+ private fun flowForAnimation(params: AnimationParams): Flow<Float> {
+ return interactor.transitionStepAnimation(
+ interactor.dreamingToLockscreenTransition,
+ params,
+ totalDuration = TO_LOCKSCREEN_DURATION
+ )
+ }
+
+ companion object {
+ /* Length of time before ending the dream activity, in order to start unoccluding */
+ val DREAM_ANIMATION_DURATION = 250.milliseconds
+
+ val DREAM_OVERLAY_TRANSLATION_Y = AnimationParams(duration = 500.milliseconds)
+ val DREAM_OVERLAY_ALPHA = AnimationParams(duration = 250.milliseconds)
+ val DREAM_BACKGROUND_ALPHA = AnimationParams(duration = 250.milliseconds)
+ val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = TO_LOCKSCREEN_DURATION)
+ val LOCKSCREEN_ALPHA =
+ AnimationParams(startTime = 233.milliseconds, duration = 250.milliseconds)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
index 227796f..5d85680 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
@@ -24,13 +24,19 @@
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
/** View-model for the keyguard bottom area view */
+@OptIn(ExperimentalCoroutinesApi::class)
class KeyguardBottomAreaViewModel
@Inject
constructor(
@@ -40,6 +46,20 @@
private val burnInHelperWrapper: BurnInHelperWrapper,
) {
/**
+ * Whether this view-model instance is powering the preview experience that renders exclusively
+ * in the wallpaper picker application. This should _always_ be `false` for the real lock screen
+ * experience.
+ */
+ private val isInPreviewMode = MutableStateFlow(false)
+
+ /**
+ * ID of the slot that's currently selected in the preview that renders exclusively in the
+ * wallpaper picker application. This is ignored for the actual, real lock screen experience.
+ */
+ private val selectedPreviewSlotId =
+ MutableStateFlow(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
+
+ /**
* Whether quick affordances are "opaque enough" to be considered visible to and interactive by
* the user. If they are not interactive, user input should not be allowed on them.
*
@@ -66,7 +86,14 @@
val isOverlayContainerVisible: Flow<Boolean> =
keyguardInteractor.isDozing.map { !it }.distinctUntilChanged()
/** An observable for the alpha level for the entire bottom area. */
- val alpha: Flow<Float> = bottomAreaInteractor.alpha.distinctUntilChanged()
+ val alpha: Flow<Float> =
+ isInPreviewMode.flatMapLatest { isInPreviewMode ->
+ if (isInPreviewMode) {
+ flowOf(1f)
+ } else {
+ bottomAreaInteractor.alpha.distinctUntilChanged()
+ }
+ }
/** An observable for whether the indication area should be padded. */
val isIndicationAreaPadded: Flow<Boolean> =
combine(startButton, endButton) { startButtonModel, endButtonModel ->
@@ -94,27 +121,61 @@
* Returns whether the keyguard bottom area should be constrained to the top of the lock icon
*/
fun shouldConstrainToTopOfLockIcon(): Boolean =
- bottomAreaInteractor.shouldConstrainToTopOfLockIcon()
+ bottomAreaInteractor.shouldConstrainToTopOfLockIcon()
+
+ /**
+ * Puts this view-model in "preview mode", which means it's being used for UI that is rendering
+ * the lock screen preview in wallpaper picker / settings and not the real experience on the
+ * lock screen.
+ *
+ * @param initiallySelectedSlotId The ID of the initial slot to render as the selected one.
+ */
+ fun enablePreviewMode(initiallySelectedSlotId: String?) {
+ isInPreviewMode.value = true
+ onPreviewSlotSelected(
+ initiallySelectedSlotId ?: KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
+ )
+ }
+
+ /**
+ * Notifies that a slot with the given ID has been selected in the preview experience that is
+ * rendering in the wallpaper picker. This is ignored for the real lock screen experience.
+ *
+ * @see enablePreviewMode
+ */
+ fun onPreviewSlotSelected(slotId: String) {
+ selectedPreviewSlotId.value = slotId
+ }
private fun button(
position: KeyguardQuickAffordancePosition
): Flow<KeyguardQuickAffordanceViewModel> {
- return combine(
- quickAffordanceInteractor.quickAffordance(position),
- bottomAreaInteractor.animateDozingTransitions.distinctUntilChanged(),
- areQuickAffordancesFullyOpaque,
- ) { model, animateReveal, isFullyOpaque ->
- model.toViewModel(
- animateReveal = animateReveal,
- isClickable = isFullyOpaque,
- )
- }
- .distinctUntilChanged()
+ return isInPreviewMode.flatMapLatest { isInPreviewMode ->
+ combine(
+ if (isInPreviewMode) {
+ quickAffordanceInteractor.quickAffordanceAlwaysVisible(position = position)
+ } else {
+ quickAffordanceInteractor.quickAffordance(position = position)
+ },
+ bottomAreaInteractor.animateDozingTransitions.distinctUntilChanged(),
+ areQuickAffordancesFullyOpaque,
+ selectedPreviewSlotId,
+ ) { model, animateReveal, isFullyOpaque, selectedPreviewSlotId ->
+ model.toViewModel(
+ animateReveal = !isInPreviewMode && animateReveal,
+ isClickable = isFullyOpaque && !isInPreviewMode,
+ isSelected =
+ (isInPreviewMode && selectedPreviewSlotId == position.toSlotId()),
+ )
+ }
+ .distinctUntilChanged()
+ }
}
private fun KeyguardQuickAffordanceModel.toViewModel(
animateReveal: Boolean,
isClickable: Boolean,
+ isSelected: Boolean,
): KeyguardQuickAffordanceViewModel {
return when (this) {
is KeyguardQuickAffordanceModel.Visible ->
@@ -131,6 +192,8 @@
},
isClickable = isClickable,
isActivated = activationState is ActivationState.Active,
+ isSelected = isSelected,
+ useLongPress = quickAffordanceInteractor.useLongPress,
)
is KeyguardQuickAffordanceModel.Hidden -> KeyguardQuickAffordanceViewModel()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt
index 44f48f9..cf3a6da 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt
@@ -29,6 +29,8 @@
val onClicked: (OnClickedParameters) -> Unit = {},
val isClickable: Boolean = false,
val isActivated: Boolean = false,
+ val isSelected: Boolean = false,
+ val useLongPress: Boolean = false,
) {
data class OnClickedParameters(
val configKey: String,
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index ec2e340..e3730af 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -102,6 +102,15 @@
return factory.create("ShadeLog", 500, false);
}
+ /** Provides a logging buffer for Shade height messages. */
+ @Provides
+ @SysUISingleton
+ @ShadeHeightLog
+ public static LogBuffer provideShadeHeightLogBuffer(LogBufferFactory factory) {
+ return factory.create("ShadeHeightLog", 500 /* maxSize */);
+ }
+
+
/** Provides a logging buffer for all logs related to managing notification sections. */
@Provides
@SysUISingleton
@@ -123,7 +132,7 @@
@SysUISingleton
@QSLog
public static LogBuffer provideQuickSettingsLogBuffer(LogBufferFactory factory) {
- return factory.create("QSLog", 500 /* maxSize */, false /* systrace */);
+ return factory.create("QSLog", 700 /* maxSize */, false /* systrace */);
}
/** Provides a logging buffer for {@link com.android.systemui.broadcast.BroadcastDispatcher} */
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/ShadeHeightLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/ShadeHeightLog.java
new file mode 100644
index 0000000..6fe8686
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/ShadeHeightLog.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.plugins.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/** A {@link LogBuffer} for Shade height changes. */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface ShadeHeightLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
index 3e5d337..bb833df 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
@@ -30,9 +30,11 @@
import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
import com.android.systemui.media.taptotransfer.MediaTttFlags;
import com.android.systemui.media.taptotransfer.common.MediaTttLogger;
+import com.android.systemui.media.taptotransfer.receiver.ChipReceiverInfo;
import com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogger;
import com.android.systemui.media.taptotransfer.sender.MediaTttSenderLogger;
import com.android.systemui.plugins.log.LogBuffer;
+import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo;
import java.util.Optional;
@@ -95,19 +97,19 @@
@Provides
@SysUISingleton
@MediaTttSenderLogger
- static MediaTttLogger providesMediaTttSenderLogger(
+ static MediaTttLogger<ChipbarInfo> providesMediaTttSenderLogger(
@MediaTttSenderLogBuffer LogBuffer buffer
) {
- return new MediaTttLogger("Sender", buffer);
+ return new MediaTttLogger<>("Sender", buffer);
}
@Provides
@SysUISingleton
@MediaTttReceiverLogger
- static MediaTttLogger providesMediaTttReceiverLogger(
+ static MediaTttLogger<ChipReceiverInfo> providesMediaTttReceiverLogger(
@MediaTttReceiverLogBuffer LogBuffer buffer
) {
- return new MediaTttLogger("Receiver", buffer);
+ return new MediaTttLogger<>("Receiver", buffer);
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index fb47d97..51b5a3d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -70,6 +70,13 @@
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
if (mController.isAdvancedLayoutSupported()) {
+ if (position >= mController.getMediaItemList().size()) {
+ if (DEBUG) {
+ Log.d(TAG, "Incorrect position: " + position + " list size: "
+ + mController.getMediaItemList().size());
+ }
+ return;
+ }
MediaItem currentMediaItem = mController.getMediaItemList().get(position);
switch (currentMediaItem.getMediaItemType()) {
case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index 3b1d861..4e08050 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -84,8 +84,7 @@
int viewType) {
mContext = viewGroup.getContext();
mHolderView = LayoutInflater.from(mContext).inflate(
- mController.isAdvancedLayoutSupported() ? MediaItem.getMediaLayoutId(
- viewType) /*R.layout.media_output_list_item_advanced*/
+ mController.isAdvancedLayoutSupported() ? MediaItem.getMediaLayoutId(viewType)
: R.layout.media_output_list_item, viewGroup, false);
return null;
@@ -308,9 +307,10 @@
updateTitleIcon(currentVolume == 0 ? R.drawable.media_output_icon_volume_off
: R.drawable.media_output_icon_volume,
mController.getColorItemContent());
+ } else {
+ animateCornerAndVolume(mSeekBar.getProgress(),
+ MediaOutputSeekbar.scaleVolumeToProgress(currentVolume));
}
- animateCornerAndVolume(mSeekBar.getProgress(),
- MediaOutputSeekbar.scaleVolumeToProgress(currentVolume));
} else {
if (!mVolumeAnimator.isStarted()) {
if (mController.isAdvancedLayoutSupported()) {
@@ -396,23 +396,18 @@
}
void updateMutedVolumeIcon() {
+ mIconAreaLayout.setBackground(
+ mContext.getDrawable(R.drawable.media_output_item_background_active));
updateTitleIcon(R.drawable.media_output_icon_volume_off,
mController.getColorItemContent());
- final GradientDrawable iconAreaBackgroundDrawable =
- (GradientDrawable) mIconAreaLayout.getBackground();
- iconAreaBackgroundDrawable.setCornerRadius(mController.getActiveRadius());
}
void updateUnmutedVolumeIcon() {
+ mIconAreaLayout.setBackground(
+ mContext.getDrawable(R.drawable.media_output_title_icon_area)
+ );
updateTitleIcon(R.drawable.media_output_icon_volume,
mController.getColorItemContent());
- final GradientDrawable iconAreaBackgroundDrawable =
- (GradientDrawable) mIconAreaLayout.getBackground();
- iconAreaBackgroundDrawable.setCornerRadii(new float[]{
- mController.getActiveRadius(),
- mController.getActiveRadius(),
- 0, 0, 0, 0, mController.getActiveRadius(), mController.getActiveRadius()
- });
}
void updateTitleIcon(@DrawableRes int id, int color) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index b436562..8eb25c4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -87,9 +87,11 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
@@ -275,7 +277,9 @@
@Override
public void onDeviceListUpdate(List<MediaDevice> devices) {
- if (mMediaDevices.isEmpty() || !mIsRefreshing) {
+ boolean isListEmpty =
+ isAdvancedLayoutSupported() ? mMediaItemList.isEmpty() : mMediaDevices.isEmpty();
+ if (isListEmpty || !mIsRefreshing) {
buildMediaDevices(devices);
mCallback.onDeviceListChanged();
} else {
@@ -646,16 +650,19 @@
for (MediaDevice device : devices) {
if (device.isMutingExpectedDevice()) {
mMediaItemList.add(0, new MediaItem(device));
+ mMediaItemList.add(1, new MediaItem(mContext.getString(
+ R.string.media_output_group_title_speakers_and_displays),
+ MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
} else {
mMediaItemList.add(new MediaItem(device));
}
}
+ mMediaItemList.add(new MediaItem());
} else {
mMediaItemList.addAll(
devices.stream().map(MediaItem::new).collect(Collectors.toList()));
+ categorizeMediaItems(null);
}
-
- categorizeMediaItems();
return;
}
// selected device exist
@@ -666,11 +673,12 @@
mMediaItemList.add(new MediaItem(device));
}
}
- categorizeMediaItems();
+ categorizeMediaItems(connectedMediaDevice);
return;
}
// To keep the same list order
final List<MediaDevice> targetMediaDevices = new ArrayList<>();
+ final Map<Integer, MediaItem> dividerItems = new HashMap<>();
for (MediaItem originalMediaItem : mMediaItemList) {
for (MediaDevice newDevice : devices) {
if (originalMediaItem.getMediaDevice().isPresent()
@@ -680,6 +688,10 @@
break;
}
}
+ if (originalMediaItem.getMediaItemType()
+ == MediaItem.MediaItemType.TYPE_GROUP_DIVIDER) {
+ dividerItems.put(mMediaItemList.indexOf(originalMediaItem), originalMediaItem);
+ }
}
if (targetMediaDevices.size() != devices.size()) {
devices.removeAll(targetMediaDevices);
@@ -688,13 +700,34 @@
mMediaItemList.clear();
mMediaItemList.addAll(
targetMediaDevices.stream().map(MediaItem::new).collect(Collectors.toList()));
- categorizeMediaItems();
+ dividerItems.forEach((key, item) -> {
+ mMediaItemList.add(key, item);
+ });
+ mMediaItemList.add(new MediaItem());
}
}
- private void categorizeMediaItems() {
+ private void categorizeMediaItems(MediaDevice connectedMediaDevice) {
synchronized (mMediaDevicesLock) {
- //TODO(255124239): do the categorization here
+ Set<String> selectedDevicesIds = getSelectedMediaDevice().stream().map(
+ MediaDevice::getId).collect(Collectors.toSet());
+ if (connectedMediaDevice != null) {
+ selectedDevicesIds.add(connectedMediaDevice.getId());
+ }
+ int latestSelected = 1;
+ for (MediaItem item : mMediaItemList) {
+ if (item.getMediaDevice().isPresent()) {
+ MediaDevice device = item.getMediaDevice().get();
+ if (selectedDevicesIds.contains(device.getId())) {
+ latestSelected = mMediaItemList.indexOf(item) + 1;
+ } else {
+ mMediaItemList.add(latestSelected, new MediaItem(mContext.getString(
+ R.string.media_output_group_title_speakers_and_displays),
+ MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
+ break;
+ }
+ }
+ }
mMediaItemList.add(new MediaItem());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
index b55bedd..8aef938 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
@@ -18,17 +18,21 @@
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.temporarydisplay.TemporaryViewInfo
import com.android.systemui.temporarydisplay.TemporaryViewLogger
/**
* A logger for media tap-to-transfer events.
*
* @param deviceTypeTag the type of device triggering the logs -- "Sender" or "Receiver".
+ *
+ * TODO(b/245610654): We should de-couple the sender and receiver loggers, since they're vastly
+ * different experiences.
*/
-class MediaTttLogger(
+class MediaTttLogger<T : TemporaryViewInfo>(
deviceTypeTag: String,
buffer: LogBuffer
-) : TemporaryViewLogger(buffer, BASE_TAG + deviceTypeTag) {
+) : TemporaryViewLogger<T>(buffer, BASE_TAG + deviceTypeTag) {
/** Logs a change in the chip state for the given [mediaRouteId]. */
fun logStateChange(stateName: String, mediaRouteId: String, packageName: String?) {
buffer.log(
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
index 009595a..066c185 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
@@ -25,6 +25,7 @@
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.TintedIcon
+import com.android.systemui.temporarydisplay.TemporaryViewInfo
/** Utility methods for media tap-to-transfer. */
class MediaTttUtils {
@@ -47,7 +48,7 @@
fun getIconInfoFromPackageName(
context: Context,
appPackageName: String?,
- logger: MediaTttLogger
+ logger: MediaTttLogger<out TemporaryViewInfo>
): IconInfo {
if (appPackageName != null) {
val packageManager = context.packageManager
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
index 40ea1e6..11348ad 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
@@ -35,6 +35,14 @@
FAR_FROM_SENDER(
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER
+ ),
+ TRANSFER_TO_RECEIVER_SUCCEEDED(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ ),
+ TRANSFER_TO_RECEIVER_FAILED(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_FAILED,
+ MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_FAILED,
);
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 1c3a53c..358534c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -37,6 +37,7 @@
import com.android.systemui.common.ui.binder.TintedIconViewBinder
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.media.taptotransfer.common.MediaTttIcon
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
@@ -45,8 +46,10 @@
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
import com.android.systemui.temporarydisplay.TemporaryViewInfo
+import com.android.systemui.temporarydisplay.ViewPriority
import com.android.systemui.util.animation.AnimationUtil.Companion.frames
import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.view.ViewUtil
import com.android.systemui.util.wakelock.WakeLock
import javax.inject.Inject
@@ -62,27 +65,31 @@
open class MediaTttChipControllerReceiver @Inject constructor(
private val commandQueue: CommandQueue,
context: Context,
- @MediaTttReceiverLogger logger: MediaTttLogger,
+ @MediaTttReceiverLogger logger: MediaTttLogger<ChipReceiverInfo>,
windowManager: WindowManager,
mainExecutor: DelayableExecutor,
accessibilityManager: AccessibilityManager,
configurationController: ConfigurationController,
+ dumpManager: DumpManager,
powerManager: PowerManager,
@Main private val mainHandler: Handler,
private val mediaTttFlags: MediaTttFlags,
private val uiEventLogger: MediaTttReceiverUiEventLogger,
private val viewUtil: ViewUtil,
wakeLockBuilder: WakeLock.Builder,
-) : TemporaryViewDisplayController<ChipReceiverInfo, MediaTttLogger>(
+ systemClock: SystemClock,
+) : TemporaryViewDisplayController<ChipReceiverInfo, MediaTttLogger<ChipReceiverInfo>>(
context,
logger,
windowManager,
mainExecutor,
accessibilityManager,
configurationController,
+ dumpManager,
powerManager,
R.layout.media_ttt_chip_receiver,
wakeLockBuilder,
+ systemClock,
) {
@SuppressLint("WrongConstant") // We're allowed to use LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
override val windowLayoutParams = commonWindowLayoutParams.apply {
@@ -123,8 +130,8 @@
}
uiEventLogger.logReceiverStateChange(chipState)
- if (chipState == ChipStateReceiver.FAR_FROM_SENDER) {
- removeView(routeInfo.id, removalReason = ChipStateReceiver.FAR_FROM_SENDER.name)
+ if (chipState != ChipStateReceiver.CLOSE_TO_SENDER) {
+ removeView(routeInfo.id, removalReason = chipState.name)
return
}
if (appIcon == null) {
@@ -158,6 +165,7 @@
}
override fun start() {
+ super.start()
if (mediaTttFlags.isMediaTttEnabled()) {
commandQueue.addCallback(commandQueueCallbacks)
}
@@ -290,4 +298,5 @@
override val windowTitle: String = MediaTttUtils.WINDOW_TITLE_RECEIVER,
override val wakeReason: String = MediaTttUtils.WAKE_REASON_RECEIVER,
override val id: String,
+ override val priority: ViewPriority = ViewPriority.NORMAL,
) : TemporaryViewInfo()
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
index 39a2763..6e515f2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
@@ -34,7 +34,11 @@
@UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_RECEIVER_* docs")
MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER(982),
@UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_RECEIVER_* docs")
- MEDIA_TTT_RECEIVER_FAR_FROM_SENDER(983);
+ MEDIA_TTT_RECEIVER_FAR_FROM_SENDER(983),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_RECEIVER_* docs")
+ MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_SUCCEEDED(1263),
+ @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_RECEIVER_* docs")
+ MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_FAILED(1264);
override fun getId() = metricId
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
index ec1984d..9f44d98 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
@@ -30,6 +30,7 @@
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.media.taptotransfer.common.MediaTttUtils
import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.temporarydisplay.ViewPriority
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import com.android.systemui.temporarydisplay.chipbar.ChipbarEndItem
import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo
@@ -46,7 +47,7 @@
private val chipbarCoordinator: ChipbarCoordinator,
private val commandQueue: CommandQueue,
private val context: Context,
- @MediaTttSenderLogger private val logger: MediaTttLogger,
+ @MediaTttSenderLogger private val logger: MediaTttLogger<ChipbarInfo>,
private val mediaTttFlags: MediaTttFlags,
private val uiEventLogger: MediaTttSenderUiEventLogger,
) : CoreStartable {
@@ -146,7 +147,7 @@
routeInfo: MediaRoute2Info,
undoCallback: IUndoMediaTransferCallback?,
context: Context,
- logger: MediaTttLogger,
+ logger: MediaTttLogger<ChipbarInfo>,
): ChipbarInfo {
val packageName = routeInfo.clientPackageName
val otherDeviceName = routeInfo.name.toString()
@@ -180,6 +181,7 @@
wakeReason = MediaTttUtils.WAKE_REASON_SENDER,
timeoutMs = chipStateSender.timeout,
id = routeInfo.id,
+ priority = ViewPriority.NORMAL,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index d762b39..bdb67ad 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -832,6 +832,11 @@
}
repositionNavigationBar(rotation);
+ // NOTE(b/260220098): In some cases, the recreated nav bar will already have the right
+ // configuration, which means that NavBarView will not receive a configuration change to
+ // propagate to EdgeBackGestureHandler (which is injected into this and NBV). As such, we
+ // should also force-update the gesture handler to ensure it updates to the right bounds
+ mEdgeBackGestureHandler.onConfigurationChanged(newConfig);
if (canShowSecondaryHandle()) {
if (rotation != mCurrentRotation) {
mCurrentRotation = rotation;
@@ -1290,8 +1295,10 @@
}
private void onVerticalChanged(boolean isVertical) {
- mCentralSurfacesOptionalLazy.get().ifPresent(statusBar ->
- statusBar.getNotificationPanelViewController().setQsScrimEnabled(!isVertical));
+ Optional<CentralSurfaces> cs = mCentralSurfacesOptionalLazy.get();
+ if (cs.isPresent() && cs.get().getNotificationPanelViewController() != null) {
+ cs.get().getNotificationPanelViewController().setQsScrimEnabled(!isVertical);
+ }
}
private boolean onNavigationTouch(View v, MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index e2f55f0..8914552 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -464,6 +464,8 @@
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
+ pw.println("mIsTablet=" + mIsTablet);
+ pw.println("mNavMode=" + mNavMode);
for (int i = 0; i < mNavigationBars.size(); i++) {
if (i > 0) {
pw.println();
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index d03ac3b..13c5b48 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -635,8 +635,9 @@
}
private void updateMLModelState() {
- boolean newState = mIsEnabled && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.USE_BACK_GESTURE_ML_MODEL, false);
+ boolean newState =
+ mIsGesturalModeEnabled && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags.USE_BACK_GESTURE_ML_MODEL, false);
if (newState == mUseMLModel) {
return;
@@ -766,7 +767,7 @@
// ML model
boolean withinMinRange = x < mMLEnableWidth + mLeftInset
|| x >= (mDisplaySize.x - mMLEnableWidth - mRightInset);
- if (!withinMinRange && mUseMLModel
+ if (!withinMinRange && mUseMLModel && !mMLModelIsLoading
&& (results = getBackGesturePredictionsCategory(x, y, app)) != -1) {
withinRange = (results == 1);
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/OWNERS b/packages/SystemUI/src/com/android/systemui/notetask/OWNERS
new file mode 100644
index 0000000..7ccb316
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 1254381
+azappone@google.com
+achalke@google.com
+juliacr@google.com
+madym@google.com
+mgalhardo@google.com
+petrcermak@google.com
+vanjan@google.com
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 8ceee1a..7523d6e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -11,7 +11,6 @@
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -31,6 +30,7 @@
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.QSPanel.QSTileLayout;
import com.android.systemui.qs.QSPanelControllerBase.TileRecord;
+import com.android.systemui.qs.logging.QSLogger;
import java.util.ArrayList;
import java.util.List;
@@ -38,11 +38,9 @@
public class PagedTileLayout extends ViewPager implements QSTileLayout {
- private static final boolean DEBUG = false;
private static final String CURRENT_PAGE = "current_page";
private static final int NO_PAGE = -1;
- private static final String TAG = "PagedTileLayout";
private static final int REVEAL_SCROLL_DURATION_MILLIS = 750;
private static final float BOUNCE_ANIMATION_TENSION = 1.3f;
private static final long BOUNCE_ANIMATION_DURATION = 450L;
@@ -55,6 +53,7 @@
private final ArrayList<TileRecord> mTiles = new ArrayList<>();
private final ArrayList<TileLayout> mPages = new ArrayList<>();
+ private QSLogger mLogger;
@Nullable
private PageIndicator mPageIndicator;
private float mPageIndicatorPosition;
@@ -146,9 +145,15 @@
}
if (mLayoutOrientation != newConfig.orientation) {
mLayoutOrientation = newConfig.orientation;
- mDistributeTiles = true;
+ forceTilesRedistribution("orientation changed to " + mLayoutOrientation);
setCurrentItem(0, false);
mPageToRestore = 0;
+ } else {
+ // logging in case we missed redistribution because orientation was not changed
+ // while configuration changed, can be removed after b/255208946 is fixed
+ mLogger.d(
+ "Orientation didn't change, tiles might be not redistributed, new config",
+ newConfig);
}
}
@@ -226,7 +231,7 @@
// Keep on drawing until the animation has finished.
postInvalidateOnAnimation();
} catch (NullPointerException e) {
- Log.e(TAG, "FakeDragBy called before begin", e);
+ mLogger.logException("FakeDragBy called before begin", e);
// If we were trying to fake drag, it means we just added a new tile to the last
// page, so animate there.
final int lastPageNumber = mPages.size() - 1;
@@ -246,7 +251,7 @@
super.endFakeDrag();
} catch (NullPointerException e) {
// Not sure what's going on. Let's log it
- Log.e(TAG, "endFakeDrag called without velocityTracker", e);
+ mLogger.logException("endFakeDrag called without velocityTracker", e);
}
}
@@ -304,14 +309,14 @@
@Override
public void addTile(TileRecord tile) {
mTiles.add(tile);
- mDistributeTiles = true;
+ forceTilesRedistribution("adding new tile");
requestLayout();
}
@Override
public void removeTile(TileRecord tile) {
if (mTiles.remove(tile)) {
- mDistributeTiles = true;
+ forceTilesRedistribution("removing tile");
requestLayout();
}
}
@@ -367,19 +372,11 @@
final int tilesPerPageCount = mPages.get(0).maxTiles();
int index = 0;
final int totalTilesCount = mTiles.size();
- if (DEBUG) {
- Log.d(TAG, "Distributing tiles: "
- + "[tilesPerPageCount=" + tilesPerPageCount + "]"
- + "[totalTilesCount=" + totalTilesCount + "]"
- );
- }
+ mLogger.logTileDistributionInProgress(tilesPerPageCount, totalTilesCount);
for (int i = 0; i < totalTilesCount; i++) {
TileRecord tile = mTiles.get(i);
if (mPages.get(index).mRecords.size() == tilesPerPageCount) index++;
- if (DEBUG) {
- Log.d(TAG, "Adding " + tile.tile.getClass().getSimpleName() + " to "
- + index);
- }
+ mLogger.logTileDistributed(tile.tile.getClass().getSimpleName(), index);
mPages.get(index).addTile(tile);
}
}
@@ -394,11 +391,11 @@
return;
}
while (mPages.size() < numPages) {
- if (DEBUG) Log.d(TAG, "Adding page");
+ mLogger.d("Adding new page");
mPages.add(createTileLayout());
}
while (mPages.size() > numPages) {
- if (DEBUG) Log.d(TAG, "Removing page");
+ mLogger.d("Removing page");
mPages.remove(mPages.size() - 1);
}
mPageIndicator.setNumPages(mPages.size());
@@ -417,8 +414,12 @@
changed |= mPages.get(i).updateResources();
}
if (changed) {
- mDistributeTiles = true;
+ forceTilesRedistribution("resources in pages changed");
requestLayout();
+ } else {
+ // logging in case we missed redistribution because number of column in updateResources
+ // was not changed, can be removed after b/255208946 is fixed
+ mLogger.d("resource in pages didn't change, tiles might be not redistributed");
}
return changed;
}
@@ -430,7 +431,7 @@
for (int i = 0; i < mPages.size(); i++) {
if (mPages.get(i).setMinRows(minRows)) {
changed = true;
- mDistributeTiles = true;
+ forceTilesRedistribution("minRows changed in page");
}
}
return changed;
@@ -443,7 +444,7 @@
for (int i = 0; i < mPages.size(); i++) {
if (mPages.get(i).setMaxColumns(maxColumns)) {
changed = true;
- mDistributeTiles = true;
+ forceTilesRedistribution("maxColumns in pages changed");
}
}
return changed;
@@ -710,14 +711,14 @@
private final PagerAdapter mAdapter = new PagerAdapter() {
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
- if (DEBUG) Log.d(TAG, "Destantiating " + position);
+ mLogger.d("Destantiating page at", position);
container.removeView((View) object);
updateListening();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
- if (DEBUG) Log.d(TAG, "Instantiating " + position);
+ mLogger.d("Instantiating page at", position);
if (isLayoutRtl()) {
position = mPages.size() - 1 - position;
}
@@ -745,10 +746,15 @@
* Force all tiles to be redistributed across pages.
* Should be called when one of the following changes: rows, columns, number of tiles.
*/
- public void forceTilesRedistribution() {
+ public void forceTilesRedistribution(String reason) {
+ mLogger.d("forcing tile redistribution across pages, reason", reason);
mDistributeTiles = true;
}
+ public void setLogger(QSLogger qsLogger) {
+ mLogger = qsLogger;
+ }
+
public interface PageListener {
int INVALID_PAGE = -1;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 6517ff3..7067c22 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -43,6 +43,7 @@
import com.android.internal.widget.RemeasuringLinearLayout;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.settings.brightness.BrightnessSliderController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -106,6 +107,7 @@
private ViewGroup mMediaHostView;
private boolean mShouldMoveMediaOnExpansion = true;
private boolean mUsingCombinedHeaders = false;
+ private QSLogger mQsLogger;
public QSPanel(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -122,7 +124,8 @@
}
- void initialize() {
+ void initialize(QSLogger qsLogger) {
+ mQsLogger = qsLogger;
mTileLayout = getOrCreateTileLayout();
if (mUsingMediaPlayer) {
@@ -206,6 +209,7 @@
if (mTileLayout == null) {
mTileLayout = (QSTileLayout) LayoutInflater.from(mContext)
.inflate(R.layout.qs_paged_tile_layout, this, false);
+ mTileLayout.setLogger(mQsLogger);
mTileLayout.setSquishinessFraction(mSquishinessFraction);
}
return mTileLayout;
@@ -735,6 +739,8 @@
default void setExpansion(float expansion, float proposedTranslation) {}
int getNumVisibleTiles();
+
+ default void setLogger(QSLogger qsLogger) { }
}
interface OnConfigurationChangedListener {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index b2ca6b7..cabe1da 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -122,9 +122,8 @@
}
switchTileLayout(true);
mBrightnessMirrorHandler.onQsPanelAttached();
-
- ((PagedTileLayout) mView.getOrCreateTileLayout())
- .setOnTouchListener(mTileLayoutTouchListener);
+ PagedTileLayout pagedTileLayout= ((PagedTileLayout) mView.getOrCreateTileLayout());
+ pagedTileLayout.setOnTouchListener(mTileLayoutTouchListener);
}
@Override
@@ -150,7 +149,8 @@
@Override
protected void onSplitShadeChanged() {
- ((PagedTileLayout) mView.getOrCreateTileLayout()).forceTilesRedistribution();
+ ((PagedTileLayout) mView.getOrCreateTileLayout())
+ .forceTilesRedistribution("Split shade state changed");
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 60d2c17..7bb672c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -70,7 +70,7 @@
protected final MediaHost mMediaHost;
protected final MetricsLogger mMetricsLogger;
private final UiEventLogger mUiEventLogger;
- private final QSLogger mQSLogger;
+ protected final QSLogger mQSLogger;
private final DumpManager mDumpManager;
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
protected boolean mShouldUseSplitNotificationShade;
@@ -152,7 +152,7 @@
@Override
protected void onInit() {
- mView.initialize();
+ mView.initialize(mQSLogger);
mQSLogger.logAllTilesChangeListening(mView.isListening(), mView.getDumpableTag(), "");
}
@@ -430,6 +430,7 @@
pw.println(" horizontal layout: " + mUsingHorizontalLayout);
pw.println(" last orientation: " + mLastOrientation);
}
+ pw.println(" mShouldUseSplitNotificationShade: " + mShouldUseSplitNotificationShade);
}
public QSPanel.QSTileLayout getTileLayout() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index c4386ab..cfda9fd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -18,6 +18,7 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -51,6 +52,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
@@ -92,6 +94,8 @@
private android.graphics.drawable.Icon mDefaultIcon;
@Nullable
private CharSequence mDefaultLabel;
+ @Nullable
+ private View mViewClicked;
private final Context mUserContext;
@@ -202,7 +206,7 @@
* Compare two icons, only works for resources.
*/
private boolean iconEquals(@Nullable android.graphics.drawable.Icon icon1,
- @Nullable android.graphics.drawable.Icon icon2) {
+ @Nullable android.graphics.drawable.Icon icon2) {
if (icon1 == icon2) {
return true;
}
@@ -229,7 +233,7 @@
/**
* Custom tile is considered available if there is a default icon (obtained from PM).
- *
+ * <p>
* It will return {@code true} before initialization, so tiles are not destroyed prematurely.
*/
@Override
@@ -262,6 +266,7 @@
/**
* Update state of {@link this#mTile} from a remote {@link TileService}.
+ *
* @param tile tile populated with state to apply
*/
public void updateTileState(Tile tile) {
@@ -293,6 +298,7 @@
if (tile.getStateDescription() != null || overwriteNulls) {
mTile.setStateDescription(tile.getStateDescription());
}
+ mTile.setActivityLaunchForClick(tile.getActivityLaunchForClick());
mTile.setState(tile.getState());
}
@@ -324,6 +330,7 @@
mService.onStartListening();
}
} else {
+ mViewClicked = null;
mService.onStopListening();
if (mIsTokenGranted && !mIsShowingDialog) {
try {
@@ -388,6 +395,7 @@
if (mTile.getState() == Tile.STATE_UNAVAILABLE) {
return;
}
+ mViewClicked = view;
try {
if (DEBUG) Log.d(TAG, "Adding token");
mWindowManager.addWindowToken(mToken, TYPE_QS_DIALOG, DEFAULT_DISPLAY,
@@ -400,7 +408,12 @@
mServiceManager.setBindRequested(true);
mService.onStartListening();
}
- mService.onClick(mToken);
+
+ if (mTile.getActivityLaunchForClick() != null) {
+ startActivityAndCollapse(mTile.getActivityLaunchForClick());
+ } else {
+ mService.onClick(mToken);
+ }
} catch (RemoteException e) {
// Called through wrapper, won't happen here.
}
@@ -483,6 +496,27 @@
});
}
+ /**
+ * Starts an {@link android.app.Activity}
+ * @param pendingIntent A PendingIntent for an Activity to be launched immediately.
+ */
+ public void startActivityAndCollapse(PendingIntent pendingIntent) {
+ if (!pendingIntent.isActivity()) {
+ Log.i(TAG, "Intent not for activity.");
+ } else if (!mIsTokenGranted) {
+ Log.i(TAG, "Launching activity before click");
+ } else {
+ Log.i(TAG, "The activity is starting");
+ ActivityLaunchAnimator.Controller controller = mViewClicked == null
+ ? null
+ : ActivityLaunchAnimator.Controller.fromView(mViewClicked, 0);
+ mUiHandler.post(() ->
+ mActivityStarter.startPendingIntentDismissingKeyguard(
+ pendingIntent, null, controller)
+ );
+ }
+ }
+
public static String toSpec(ComponentName name) {
return PREFIX + name.flattenToShortString() + ")";
}
@@ -509,8 +543,8 @@
/**
* Create a {@link CustomTile} for a given spec and user.
*
- * @param builder including injected common dependencies.
- * @param spec as provided by {@link CustomTile#toSpec}
+ * @param builder including injected common dependencies.
+ * @param spec as provided by {@link CustomTile#toSpec}
* @param userContext context for the user that is creating this tile.
* @return a new {@link CustomTile}
*/
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 5d03da3..3d48fd1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -15,6 +15,7 @@
*/
package com.android.systemui.qs.external;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageInfo;
@@ -32,6 +33,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -276,6 +278,19 @@
}
@Override
+ public void startActivity(IBinder token, PendingIntent pendingIntent) {
+ startActivity(getTileForToken(token), pendingIntent);
+ }
+
+ @VisibleForTesting
+ protected void startActivity(CustomTile customTile, PendingIntent pendingIntent) {
+ if (customTile != null) {
+ verifyCaller(customTile);
+ customTile.startActivityAndCollapse(pendingIntent);
+ }
+ }
+
+ @Override
public void updateStatusIcon(IBinder token, Icon icon, String contentDescription) {
CustomTile customTile = getTileForToken(token);
if (customTile != null) {
@@ -336,7 +351,7 @@
}
@Nullable
- private CustomTile getTileForToken(IBinder token) {
+ public CustomTile getTileForToken(IBinder token) {
synchronized (mServices) {
return mTokenMap.get(token);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
index 6db3c99..30f8124 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
@@ -237,7 +237,13 @@
return
}
- buttonView.setBackgroundResource(model.background)
+ val backgroundResource =
+ when (model.backgroundColor) {
+ R.attr.offStateColor -> R.drawable.qs_footer_action_circle
+ com.android.internal.R.attr.colorAccent -> R.drawable.qs_footer_action_circle_color
+ else -> error("Unsupported icon background resource ${model.backgroundColor}")
+ }
+ buttonView.setBackgroundResource(backgroundResource)
buttonView.setOnClickListener { model.onClick(Expandable.fromView(buttonView)) }
val icon = model.icon
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt
index 8d819da..2670787 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt
@@ -16,7 +16,8 @@
package com.android.systemui.qs.footer.ui.viewmodel
-import android.annotation.DrawableRes
+import android.annotation.AttrRes
+import android.annotation.ColorInt
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
@@ -27,7 +28,7 @@
data class FooterActionsButtonViewModel(
val id: Int,
val icon: Icon,
- val iconTint: Int?,
- @DrawableRes val background: Int,
+ @ColorInt val iconTint: Int?,
+ @AttrRes val backgroundColor: Int,
val onClick: (Expandable) -> Unit,
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
index dee6fad..fbf32b3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
@@ -18,6 +18,7 @@
import android.content.Context
import android.util.Log
+import android.view.ContextThemeWrapper
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
@@ -49,12 +50,15 @@
/** A ViewModel for the footer actions. */
class FooterActionsViewModel(
- @Application private val context: Context,
+ @Application appContext: Context,
private val footerActionsInteractor: FooterActionsInteractor,
private val falsingManager: FalsingManager,
private val globalActionsDialogLite: GlobalActionsDialogLite,
showPowerButton: Boolean,
) {
+ /** The context themed with the Quick Settings colors. */
+ private val context = ContextThemeWrapper(appContext, R.style.Theme_SystemUI_QuickSettings)
+
/**
* Whether the UI rendering this ViewModel should be visible. Note that even when this is false,
* the UI should still participate to the layout it is included in (i.e. in the View world it
@@ -142,7 +146,7 @@
ContentDescription.Resource(R.string.accessibility_quick_settings_settings)
),
iconTint = null,
- R.drawable.qs_footer_action_circle,
+ backgroundColor = R.attr.offStateColor,
this::onSettingsButtonClicked,
)
@@ -160,7 +164,7 @@
context,
com.android.internal.R.attr.textColorOnAccent,
),
- R.drawable.qs_footer_action_circle_color,
+ backgroundColor = com.android.internal.R.attr.colorAccent,
this::onPowerButtonClicked,
)
} else {
@@ -260,7 +264,7 @@
),
),
iconTint = null,
- background = R.drawable.qs_footer_action_circle,
+ backgroundColor = R.attr.offStateColor,
onClick = this::onUserSwitcherClicked,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
index 9f6317f..d682853f5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
@@ -21,10 +21,13 @@
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogLevel
import com.android.systemui.plugins.log.LogLevel.DEBUG
+import com.android.systemui.plugins.log.LogLevel.ERROR
import com.android.systemui.plugins.log.LogLevel.VERBOSE
+import com.android.systemui.plugins.log.LogLevel.WARNING
import com.android.systemui.plugins.log.LogMessage
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.statusbar.StatusBarState
+import com.google.errorprone.annotations.CompileTimeConstant
import javax.inject.Inject
private const val TAG = "QSLog"
@@ -33,6 +36,26 @@
@QSLog private val buffer: LogBuffer
) {
+ fun d(@CompileTimeConstant msg: String) = buffer.log(TAG, DEBUG, msg)
+
+ fun e(@CompileTimeConstant msg: String) = buffer.log(TAG, ERROR, msg)
+
+ fun v(@CompileTimeConstant msg: String) = buffer.log(TAG, VERBOSE, msg)
+
+ fun w(@CompileTimeConstant msg: String) = buffer.log(TAG, WARNING, msg)
+
+ fun logException(@CompileTimeConstant logMsg: String, ex: Exception) {
+ buffer.log(TAG, ERROR, {}, { logMsg }, exception = ex)
+ }
+
+ fun v(@CompileTimeConstant msg: String, arg: Any) {
+ buffer.log(TAG, VERBOSE, { str1 = arg.toString() }, { "$msg: $str1" })
+ }
+
+ fun d(@CompileTimeConstant msg: String, arg: Any) {
+ buffer.log(TAG, DEBUG, { str1 = arg.toString() }, { "$msg: $str1" })
+ }
+
fun logTileAdded(tileSpec: String) {
log(DEBUG, {
str1 = tileSpec
@@ -236,6 +259,24 @@
})
}
+ fun logTileDistributionInProgress(tilesPerPageCount: Int, totalTilesCount: Int) {
+ log(DEBUG, {
+ int1 = tilesPerPageCount
+ int2 = totalTilesCount
+ }, {
+ "Distributing tiles: [tilesPerPageCount=$int1] [totalTilesCount=$int2]"
+ })
+ }
+
+ fun logTileDistributed(tileName: String, pageIndex: Int) {
+ log(DEBUG, {
+ str1 = tileName
+ int1 = pageIndex
+ }, {
+ "Adding $str1 to page number $int1"
+ })
+ }
+
private fun toStateString(state: Int): String {
return when (state) {
Tile.STATE_ACTIVE -> "active"
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 00d129a..4d005be 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -889,7 +889,7 @@
* Notifies the Launcher that screen is starting to turn on.
*/
@Override
- public void onScreenTurningOn(@NonNull Runnable ignored) {
+ public void onScreenTurningOn() {
try {
if (mOverviewProxy != null) {
mOverviewProxy.onScreenTurningOn();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 9c7718d..e8ceb52 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -289,6 +289,9 @@
mDismissButton.getBoundsOnScreen(tmpRect);
swipeRegion.op(tmpRect, Region.Op.UNION);
+ mMessageContainer.findViewById(R.id.message_dismiss_button).getBoundsOnScreen(tmpRect);
+ swipeRegion.op(tmpRect, Region.Op.UNION);
+
return swipeRegion;
}
@@ -353,6 +356,9 @@
mMessageContent.setText(
mContext.getString(R.string.screenshot_work_profile_notification, appName));
mMessageContainer.setVisibility(VISIBLE);
+ mMessageContainer.findViewById(R.id.message_dismiss_button).setOnClickListener((v) -> {
+ mMessageContainer.setVisibility(View.GONE);
+ });
}
@Override // View
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 6ad0b9a..fcdde79 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -632,6 +632,7 @@
private final KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
private final KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
private float mMinExpandHeight;
+ private ShadeHeightLogger mShadeHeightLogger;
private boolean mPanelUpdateWhenAnimatorEnds;
private boolean mHasVibratedOnOpen = false;
private int mFixedDuration = NO_FIXED_DURATION;
@@ -711,6 +712,7 @@
KeyguardUpdateMonitor keyguardUpdateMonitor,
MetricsLogger metricsLogger,
ShadeLogger shadeLogger,
+ ShadeHeightLogger shadeHeightLogger,
ConfigurationController configurationController,
Provider<FlingAnimationUtils.Builder> flingAnimationUtilsBuilder,
StatusBarTouchableRegionManager statusBarTouchableRegionManager,
@@ -771,6 +773,7 @@
mLockscreenGestureLogger = lockscreenGestureLogger;
mShadeExpansionStateManager = shadeExpansionStateManager;
mShadeLog = shadeLogger;
+ mShadeHeightLogger = shadeHeightLogger;
mGutsManager = gutsManager;
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
@@ -1328,7 +1331,9 @@
mKeyguardBottomArea.init(
mKeyguardBottomAreaViewModel,
mFalsingManager,
- mLockIconViewController
+ mLockIconViewController,
+ stringResourceId ->
+ mKeyguardIndicationController.showTransientIndication(stringResourceId)
);
}
@@ -1813,6 +1818,7 @@
waiting = true;
} else {
resetViews(false /* animate */);
+ mShadeHeightLogger.logFunctionCall("collapsePanel");
setExpandedFraction(0); // just in case
}
if (!waiting) {
@@ -3689,6 +3695,7 @@
beginJankMonitoring();
fling(0 /* expand */);
} else {
+ mShadeHeightLogger.logFunctionCall("expand");
setExpandedFraction(1f);
}
mInstantExpanding = false;
@@ -4753,6 +4760,7 @@
mInitialTouchFromKeyguard = mKeyguardStateController.isShowing();
if (startTracking) {
mTouchSlopExceeded = true;
+ mShadeHeightLogger.logFunctionCall("startExpandMotion");
setExpandedHeight(mInitialOffsetOnTouch);
onTrackingStarted();
}
@@ -4898,6 +4906,7 @@
@VisibleForTesting
void setExpandedHeight(float height) {
debugLog("setExpandedHeight(%.1f)", height);
+ mShadeHeightLogger.logFunctionCall("setExpandedHeight");
setExpandedHeightInternal(height);
}
@@ -4921,10 +4930,13 @@
return;
}
+ mShadeHeightLogger.logFunctionCall("updateExpandedHeightToMaxHeight");
setExpandedHeight(currentMaxPanelHeight);
}
private void setExpandedHeightInternal(float h) {
+ mShadeHeightLogger.logSetExpandedHeightInternal(h, mSystemClock.currentTimeMillis());
+
if (isNaN(h)) {
Log.wtf(TAG, "ExpandedHeight set to NaN");
}
@@ -4981,7 +4993,9 @@
/** Sets the expanded height relative to a number from 0 to 1. */
public void setExpandedFraction(float frac) {
- setExpandedHeight(getMaxPanelTransitionDistance() * frac);
+ final int maxDist = getMaxPanelTransitionDistance();
+ mShadeHeightLogger.logFunctionCall("setExpandedFraction");
+ setExpandedHeight(maxDist * frac);
}
float getExpandedHeight() {
@@ -4992,10 +5006,37 @@
return mExpandedFraction;
}
+ /**
+ * This method should not be used anymore, you should probably use {@link #isShadeFullyOpen()}
+ * instead. It was overused as indicating if shade is open or we're on keyguard/AOD.
+ * Moving forward we should be explicit about the what state we're checking.
+ * @return if panel is covering the screen, which means we're in expanded shade or keyguard/AOD
+ *
+ * @deprecated depends on the state you check, use {@link #isShadeFullyOpen()},
+ * {@link #isOnAod()}, {@link #isOnKeyguard()} instead.
+ */
+ @Deprecated
public boolean isFullyExpanded() {
return mExpandedHeight >= getMaxPanelTransitionDistance();
}
+ /**
+ * Returns true if shade is fully opened, that is we're actually in the notification shade
+ * with QQS or QS. It's different from {@link #isFullyExpanded()} that it will not report
+ * shade as always expanded if we're on keyguard/AOD. It will return true only when user goes
+ * from keyguard to shade.
+ */
+ public boolean isShadeFullyOpen() {
+ if (mBarState == SHADE) {
+ return isFullyExpanded();
+ } else if (mBarState == SHADE_LOCKED) {
+ return true;
+ } else {
+ // case of two finger swipe from the top of keyguard
+ return computeQsExpansionFraction() == 1;
+ }
+ }
+
public boolean isFullyCollapsed() {
return mExpandedFraction <= 0.0f;
}
@@ -5016,6 +5057,7 @@
/** Collapses the shade instantly without animation. */
public void instantCollapse() {
abortAnimations();
+ mShadeHeightLogger.logFunctionCall("instantCollapse");
setExpandedFraction(0f);
if (mExpanding) {
notifyExpandingFinished();
@@ -5132,6 +5174,7 @@
animator.getAnimatedFraction()));
setOverExpansionInternal(expansion, false /* isFromGesture */);
}
+ mShadeHeightLogger.logFunctionCall("height animator update");
setExpandedHeightInternal((float) animation.getAnimatedValue());
});
return animator;
@@ -5606,6 +5649,7 @@
mStatusBarStateController.setUpcomingState(KEYGUARD);
mStatusBarStateListener.onStateChanged(KEYGUARD);
mStatusBarStateListener.onDozeAmountChanged(1f, 1f);
+ mShadeHeightLogger.logFunctionCall("showAodUi");
setExpandedFraction(1f);
}
@@ -6152,6 +6196,7 @@
// otherwise {@link NotificationStackScrollLayout}
// wrongly enables stack height updates at the start of lockscreen swipe-up
mAmbientState.setSwipingUp(h <= 0);
+ mShadeHeightLogger.logFunctionCall("ACTION_MOVE");
setExpandedHeightInternal(newHeight);
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
index a41a15d..ad5a68e4d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
@@ -63,8 +63,14 @@
*/
boolean closeShadeIfOpen();
- /** Returns whether the shade is currently open or opening. */
- boolean isShadeOpen();
+ /**
+ * Returns whether the shade is currently open.
+ * Even though in the current implementation shade is in expanded state on keyguard, this
+ * method makes distinction between shade being truly open and plain keyguard state:
+ * - if QS and notifications are visible on the screen, return true
+ * - for any other state, including keyguard, return false
+ */
+ boolean isShadeFullyOpen();
/**
* Add a runnable for NotificationPanelView to post when the panel is expanded.
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
index 638e748..026673a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
@@ -154,9 +154,8 @@
}
@Override
- public boolean isShadeOpen() {
- return mNotificationPanelViewController.isExpanding()
- || mNotificationPanelViewController.isFullyExpanded();
+ public boolean isShadeFullyOpen() {
+ return mNotificationPanelViewController.isShadeFullyOpen();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeEventsModule.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeEventsModule.java
index 959c339..f87a1ed 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeEventsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeEventsModule.java
@@ -16,14 +16,17 @@
package com.android.systemui.shade;
-import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.shade.data.repository.ShadeRepository;
+import com.android.systemui.shade.data.repository.ShadeRepositoryImpl;
import dagger.Binds;
import dagger.Module;
-/** Provides a {@link ShadeStateEvents} in {@link SysUISingleton} scope. */
+/** Provides Shade-related events and information. */
@Module
public abstract class ShadeEventsModule {
@Binds
abstract ShadeStateEvents bindShadeEvents(ShadeExpansionStateManager impl);
+
+ @Binds abstract ShadeRepository shadeRepository(ShadeRepositoryImpl impl);
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeightLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeightLogger.kt
new file mode 100644
index 0000000..e610b98
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeightLogger.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.shade
+
+import com.android.systemui.log.dagger.ShadeHeightLog
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel.DEBUG
+import java.text.SimpleDateFormat
+import javax.inject.Inject
+
+private const val TAG = "ShadeHeightLogger"
+
+/**
+ * Log the call stack for [NotificationPanelViewController] setExpandedHeightInternal.
+ *
+ * Tracking bug: b/261593829
+ */
+class ShadeHeightLogger
+@Inject constructor(
+ @ShadeHeightLog private val buffer: LogBuffer,
+) {
+
+ private val dateFormat = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS")
+
+ fun logFunctionCall(functionName: String) {
+ buffer.log(TAG, DEBUG, {
+ str1 = functionName
+ }, {
+ "$str1"
+ })
+ }
+
+ fun logSetExpandedHeightInternal(h: Float, time: Long) {
+ buffer.log(TAG, DEBUG, {
+ double1 = h.toDouble()
+ long1 = time
+ }, {
+ "setExpandedHeightInternal=$double1 time=${dateFormat.format(long1)}"
+ })
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
index 09019a6..bf7a2be 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
@@ -27,11 +27,17 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
+interface ShadeRepository {
+ /** ShadeModel information regarding shade expansion events */
+ val shadeModel: Flow<ShadeModel>
+}
+
/** Business logic for shade interactions */
@SysUISingleton
-class ShadeRepository @Inject constructor(shadeExpansionStateManager: ShadeExpansionStateManager) {
-
- val shadeModel: Flow<ShadeModel> =
+class ShadeRepositoryImpl
+@Inject
+constructor(shadeExpansionStateManager: ShadeExpansionStateManager) : ShadeRepository {
+ override val shadeModel: Flow<ShadeModel> =
conflatedCallbackFlow {
val callback =
object : ShadeExpansionListener {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 0f27420..b7001e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -1193,8 +1193,12 @@
}
@Override
- public void onTrustGrantedForCurrentUser(boolean dismissKeyguard,
- @NonNull TrustGrantFlags flags, @Nullable String message) {
+ public void onTrustGrantedForCurrentUser(
+ boolean dismissKeyguard,
+ boolean newlyUnlocked,
+ @NonNull TrustGrantFlags flags,
+ @Nullable String message
+ ) {
showTrustGrantedMessage(dismissKeyguard, message);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index f668528..3516037 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -463,7 +463,11 @@
riv.getController().setRemoteInput(input);
riv.getController().setRemoteInputs(inputs);
riv.getController().setEditedSuggestionInfo(editedSuggestionInfo);
- riv.focusAnimated();
+ ViewGroup parent = view.getParent() != null ? (ViewGroup) view.getParent() : null;
+ if (parent != null) {
+ riv.setDefocusTargetHeight(parent.getHeight());
+ }
+ riv.focusAnimated(parent);
if (userMessageContent != null) {
riv.setEditTextContent(userMessageContent);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt
index 42edb30..c22dbf6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt
@@ -27,8 +27,10 @@
/**
* The top position of the notification at the start of the animation. This is needed in order
* to keep the notification at its place when launching a notification that is clipped rounded.
+ * This value is in absolute screen coordinates.
*/
- var startNotificationTop = 0f
+ var startNotificationTop = 0
+ var notificationParentTop = 0
var startClipTopAmount = 0
var parentStartClipTopAmount = 0
var progress = 0f
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index 0d35fdc..798bbe8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -92,11 +92,12 @@
)
params.startTranslationZ = notification.translationZ
- params.startNotificationTop = notification.translationY
+ params.startNotificationTop = location[1]
+ params.notificationParentTop = notificationListContainer
+ .getViewParentForNotification(notificationEntry).locationOnScreen[1]
params.startRoundedTopClipping = roundedTopClipping
params.startClipTopAmount = notification.clipTopAmount
if (notification.isChildInGroup) {
- params.startNotificationTop += notification.notificationParent.translationY
val locationOnScreen = notification.notificationParent.locationOnScreen[1]
val parentRoundedClip = (clipStartLocation - locationOnScreen).coerceAtLeast(0)
params.parentStartRoundedTopClipping = parentRoundedClip
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
index 0eb0000..dc9b416 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
@@ -306,9 +306,12 @@
*/
class RoundableState(
internal val targetView: View,
- roundable: Roundable,
- internal val maxRadius: Float,
+ private val roundable: Roundable,
+ maxRadius: Float,
) {
+ internal var maxRadius = maxRadius
+ private set
+
/** Animatable for top roundness */
private val topAnimatable = topAnimatable(roundable)
@@ -356,6 +359,13 @@
PropertyAnimator.setProperty(targetView, bottomAnimatable, value, DURATION, animated)
}
+ fun setMaxRadius(radius: Float) {
+ if (maxRadius != radius) {
+ maxRadius = radius
+ roundable.applyRoundnessAndInvalidate()
+ }
+ }
+
fun debugString() = buildString {
append("TargetView: ${targetView.hashCode()} ")
append("Top: $topRoundness ")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
index 4133802..76252d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
@@ -16,8 +16,13 @@
package com.android.systemui.statusbar.notification.collection.coordinator
+import android.database.ContentObserver
+import android.os.UserHandle
+import android.provider.Settings
import androidx.annotation.VisibleForTesting
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.StatusBarState
@@ -30,11 +35,20 @@
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.settings.SettingsProxy
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
/**
@@ -45,16 +59,19 @@
class KeyguardCoordinator
@Inject
constructor(
+ @Background private val bgDispatcher: CoroutineDispatcher,
private val keyguardNotificationVisibilityProvider: KeyguardNotificationVisibilityProvider,
private val keyguardRepository: KeyguardRepository,
private val notifPipelineFlags: NotifPipelineFlags,
@Application private val scope: CoroutineScope,
private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
+ private val secureSettings: SecureSettings,
private val seenNotifsProvider: SeenNotificationsProviderImpl,
private val statusBarStateController: StatusBarStateController,
) : Coordinator {
private val unseenNotifications = mutableSetOf<NotificationEntry>()
+ private var unseenFilterEnabled = false
override fun attach(pipeline: NotifPipeline) {
setupInvalidateNotifListCallbacks()
@@ -71,6 +88,7 @@
pipeline.addFinalizeFilter(unseenNotifFilter)
pipeline.addCollectionListener(collectionListener)
scope.launch { clearUnseenWhenKeyguardIsDismissed() }
+ scope.launch { invalidateWhenUnseenSettingChanges() }
}
private suspend fun clearUnseenWhenKeyguardIsDismissed() {
@@ -85,6 +103,36 @@
}
}
+ private suspend fun invalidateWhenUnseenSettingChanges() {
+ secureSettings
+ // emit whenever the setting has changed
+ .settingChangesForUser(
+ Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
+ UserHandle.USER_ALL,
+ )
+ // perform a query immediately
+ .onStart { emit(Unit) }
+ // for each change, lookup the new value
+ .map {
+ secureSettings.getBoolForUser(
+ Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
+ UserHandle.USER_CURRENT,
+ )
+ }
+ // perform lookups on the bg thread pool
+ .flowOn(bgDispatcher)
+ // only track the most recent emission, if events are happening faster than they can be
+ // consumed
+ .conflate()
+ // update local field and invalidate if necessary
+ .collect { setting ->
+ if (setting != unseenFilterEnabled) {
+ unseenFilterEnabled = setting
+ unseenNotifFilter.invalidateList("unseen setting changed")
+ }
+ }
+ }
+
private val collectionListener =
object : NotifCollectionListener {
override fun onEntryAdded(entry: NotificationEntry) {
@@ -112,6 +160,8 @@
override fun shouldFilterOut(entry: NotificationEntry, now: Long): Boolean =
when {
+ // Don't apply filter if the setting is disabled
+ !unseenFilterEnabled -> false
// Don't apply filter if the keyguard isn't currently showing
!keyguardRepository.isKeyguardShowing() -> false
// Don't apply the filter if the notification is unseen
@@ -165,3 +215,15 @@
private val SEEN_TIMEOUT = 5.seconds
}
}
+
+private fun SettingsProxy.settingChangesForUser(name: String, userHandle: Int): Flow<Unit> =
+ conflatedCallbackFlow {
+ val observer =
+ object : ContentObserver(null) {
+ override fun onChange(selfChange: Boolean) {
+ trySend(Unit)
+ }
+ }
+ registerContentObserverForUser(name, observer, userHandle)
+ awaitClose { unregisterContentObserver(observer) }
+ }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 47cdde4..56eb4b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.collection.inflation;
+import static com.android.systemui.flags.Flags.NOTIFICATION_INLINE_REPLY_ANIMATION;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
@@ -30,6 +31,7 @@
import com.android.internal.util.NotificationMessagingUtil;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -71,6 +73,7 @@
private NotificationListContainer mListContainer;
private BindRowCallback mBindRowCallback;
private NotificationClicker mNotificationClicker;
+ private FeatureFlags mFeatureFlags;
@Inject
public NotificationRowBinderImpl(
@@ -82,7 +85,8 @@
RowContentBindStage rowContentBindStage,
Provider<RowInflaterTask> rowInflaterTaskProvider,
ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder,
- IconManager iconManager) {
+ IconManager iconManager,
+ FeatureFlags featureFlags) {
mContext = context;
mNotifBindPipeline = notifBindPipeline;
mRowContentBindStage = rowContentBindStage;
@@ -92,6 +96,7 @@
mRowInflaterTaskProvider = rowInflaterTaskProvider;
mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder;
mIconManager = iconManager;
+ mFeatureFlags = featureFlags;
}
/**
@@ -176,6 +181,8 @@
entry.setRow(row);
mNotifBindPipeline.manageRow(entry, row);
mBindRowCallback.onBindRow(row);
+ row.setInlineReplyAnimationFlagEnabled(
+ mFeatureFlags.isEnabled(NOTIFICATION_INLINE_REPLY_ANIMATION));
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeRepo.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeRepo.kt
new file mode 100644
index 0000000..b483228
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeRepo.kt
@@ -0,0 +1,102 @@
+package com.android.systemui.statusbar.notification.fsi
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.pm.PackageManager
+import android.graphics.drawable.Drawable
+import android.os.RemoteException
+import android.service.dreams.IDreamManager
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.LaunchFullScreenIntentProvider
+import com.android.systemui.statusbar.notification.fsi.FsiDebug.Companion.log
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+/**
+ * Class that bridges the gap between clean app architecture and existing code. Provides new
+ * implementation of StatusBarNotificationActivityStarter launchFullscreenIntent that pipes
+ * one-directional data => FsiChromeViewModel => FsiChromeView.
+ */
+@SysUISingleton
+class FsiChromeRepo
+@Inject
+constructor(
+ private val context: Context,
+ private val pm: PackageManager,
+ private val keyguardRepo: KeyguardRepository,
+ private val launchFullScreenIntentProvider: LaunchFullScreenIntentProvider,
+ private val featureFlags: FeatureFlags,
+ private val uiBgExecutor: Executor,
+ private val dreamManager: IDreamManager,
+ private val centralSurfaces: CentralSurfaces
+) : CoreStartable {
+
+ companion object {
+ private const val classTag = "FsiChromeRepo"
+ }
+
+ data class FSIInfo(
+ val appName: String,
+ val appIcon: Drawable,
+ val fullscreenIntent: PendingIntent
+ )
+
+ private val _infoFlow = MutableStateFlow<FSIInfo?>(null)
+ val infoFlow: StateFlow<FSIInfo?> = _infoFlow
+
+ override fun start() {
+ log("$classTag start listening for FSI notifications")
+
+ // Listen for FSI launch events for the lifetime of SystemUI.
+ launchFullScreenIntentProvider.registerListener { entry -> launchFullscreenIntent(entry) }
+ }
+
+ fun dismiss() {
+ _infoFlow.value = null
+ }
+
+ fun onFullscreen() {
+ // TODO(b/243421660) implement transition from container to fullscreen
+ }
+
+ fun stopScreenSaver() {
+ uiBgExecutor.execute {
+ try {
+ dreamManager.awaken()
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ fun launchFullscreenIntent(entry: NotificationEntry) {
+ if (!featureFlags.isEnabled(Flags.FSI_CHROME)) {
+ return
+ }
+ if (!keyguardRepo.isKeyguardShowing()) {
+ return
+ }
+ stopScreenSaver()
+
+ var appName = pm.getApplicationLabel(context.applicationInfo) as String
+ val appIcon = pm.getApplicationIcon(context.packageName)
+ val fullscreenIntent = entry.sbn.notification.fullScreenIntent
+
+ log("FsiChromeRepo launchFullscreenIntent appName=$appName appIcon $appIcon")
+ _infoFlow.value = FSIInfo(appName, appIcon, fullscreenIntent)
+
+ // If screen is off or we're showing AOD, show lockscreen.
+ centralSurfaces.wakeUpForFullScreenIntent()
+
+ // Don't show HUN since we're already showing FSI.
+ entry.notifyFullScreenIntentLaunched()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeView.kt
new file mode 100644
index 0000000..6e5fcf40
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeView.kt
@@ -0,0 +1,83 @@
+package com.android.systemui.statusbar.notification.fsi
+
+import android.content.Context
+import android.graphics.Color
+import android.graphics.Color.DKGRAY
+import android.graphics.Outline
+import android.util.AttributeSet
+import android.view.View
+import android.view.ViewOutlineProvider
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.fsi.FsiDebug.Companion.log
+
+@SysUISingleton
+class FsiChromeView
+@JvmOverloads
+constructor(
+ context: Context?,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+ defStyleRes: Int = 0
+) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) {
+
+ companion object {
+ private const val classTag = "FsiChromeView"
+ }
+
+ lateinit var chromeContainer: LinearLayout
+ lateinit var appIconImageView: ImageView
+ lateinit var appNameTextView: TextView
+ lateinit var dismissButton: Button
+ lateinit var fullscreenButton: Button
+
+ private val cornerRadius: Float =
+ resources.getDimensionPixelSize(R.dimen.notification_corner_radius).toFloat()
+ private val vertPadding: Int =
+ resources.getDimensionPixelSize(R.dimen.fsi_chrome_vertical_padding)
+ private val sidePadding: Int =
+ resources.getDimensionPixelSize(R.dimen.notification_side_paddings)
+
+ init {
+ log("$classTag init")
+ }
+
+ override fun onFinishInflate() {
+ log("$classTag onFinishInflate")
+ super.onFinishInflate()
+
+ setBackgroundColor(Color.TRANSPARENT)
+ setPadding(
+ sidePadding,
+ vertPadding,
+ sidePadding,
+ vertPadding
+ ) // Make smaller than fullscreen.
+
+ chromeContainer = findViewById(R.id.fsi_chrome)
+ chromeContainer.setBackgroundColor(DKGRAY)
+
+ appIconImageView = findViewById(R.id.fsi_app_icon)
+ appNameTextView = findViewById(R.id.fsi_app_name)
+ dismissButton = findViewById(R.id.fsi_dismiss_button)
+ fullscreenButton = findViewById(R.id.fsi_fullscreen_button)
+
+ outlineProvider =
+ object : ViewOutlineProvider() {
+ override fun getOutline(view: View, outline: Outline) {
+ outline.setRoundRect(
+ /* left */ sidePadding,
+ /* top */ vertPadding,
+ /* right */ view.width - sidePadding,
+ /* bottom */ view.height - vertPadding,
+ cornerRadius
+ )
+ }
+ }
+ clipToOutline = true
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeViewModelFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeViewModelFactory.kt
new file mode 100644
index 0000000..1ca698b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeViewModelFactory.kt
@@ -0,0 +1,87 @@
+package com.android.systemui.statusbar.notification.fsi
+
+import android.annotation.UiContext
+import android.app.PendingIntent
+import android.content.Context
+import android.graphics.drawable.Drawable
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.statusbar.notification.fsi.FsiDebug.Companion.log
+import com.android.wm.shell.TaskView
+import com.android.wm.shell.TaskViewFactory
+import java.util.Optional
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import kotlin.coroutines.resume
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+/**
+ * Handle view-related data for fullscreen intent container on lockscreen. Wraps FsiChromeRepo,
+ * transforms events/state into view-relevant representation for FsiChromeView. Alive for lifetime
+ * of SystemUI.
+ */
+@SysUISingleton
+class FsiChromeViewModelFactory
+@Inject
+constructor(
+ val repo: FsiChromeRepo,
+ val taskViewFactory: Optional<TaskViewFactory>,
+ @UiContext val context: Context,
+ @Main val mainExecutor: Executor,
+) : CoreStartable {
+
+ companion object {
+ private const val classTag = "FsiChromeViewModelFactory"
+ }
+
+ val viewModelFlow: Flow<FsiChromeViewModel?> =
+ repo.infoFlow.mapLatest { fsiInfo ->
+ fsiInfo?.let {
+ log("$classTag viewModelFlow got new fsiInfo")
+
+ // mapLatest emits null when FSIInfo is null
+ FsiChromeViewModel(
+ fsiInfo.appName,
+ fsiInfo.appIcon,
+ createTaskView(),
+ fsiInfo.fullscreenIntent,
+ repo
+ )
+ }
+ }
+
+ override fun start() {
+ log("$classTag start")
+ }
+
+ private suspend fun createTaskView(): TaskView = suspendCancellableCoroutine { k ->
+ log("$classTag createTaskView")
+
+ taskViewFactory.get().create(context, mainExecutor) { taskView -> k.resume(taskView) }
+ }
+}
+
+// Alive for lifetime of FSI.
+data class FsiChromeViewModel(
+ val appName: String,
+ val appIcon: Drawable,
+ val taskView: TaskView,
+ val fsi: PendingIntent,
+ val repo: FsiChromeRepo
+) {
+ companion object {
+ private const val classTag = "FsiChromeViewModel"
+ }
+
+ fun onDismiss() {
+ log("$classTag onDismiss")
+ repo.dismiss()
+ }
+ fun onFullscreen() {
+ log("$classTag onFullscreen")
+ repo.onFullscreen()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemory.kt
index 0380fff..1fcf17f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemory.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemory.kt
@@ -17,10 +17,14 @@
package com.android.systemui.statusbar.notification.logging
+import android.app.Notification
+
/** Describes usage of a notification. */
data class NotificationMemoryUsage(
val packageName: String,
+ val uid: Int,
val notificationKey: String,
+ val notification: Notification,
val objectUsage: NotificationObjectUsage,
val viewUsage: List<NotificationViewUsage>
)
@@ -34,7 +38,8 @@
val smallIcon: Int,
val largeIcon: Int,
val extras: Int,
- val style: String?,
+ /** Style type, integer from [android.stats.sysui.NotificationEnums] */
+ val style: Int,
val styleIcon: Int,
val bigPicture: Int,
val extender: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt
new file mode 100644
index 0000000..ffd931c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt
@@ -0,0 +1,173 @@
+/*
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.logging
+
+import android.stats.sysui.NotificationEnums
+import com.android.systemui.Dumpable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import java.io.PrintWriter
+import javax.inject.Inject
+
+/** Dumps current notification memory use to bug reports for easier debugging. */
+@SysUISingleton
+class NotificationMemoryDumper
+@Inject
+constructor(val dumpManager: DumpManager, val notificationPipeline: NotifPipeline) : Dumpable {
+
+ fun init() {
+ dumpManager.registerNormalDumpable(javaClass.simpleName, this)
+ }
+
+ override fun dump(pw: PrintWriter, args: Array<out String>) {
+ val memoryUse =
+ NotificationMemoryMeter.notificationMemoryUse(notificationPipeline.allNotifs)
+ .sortedWith(compareBy({ it.packageName }, { it.notificationKey }))
+ dumpNotificationObjects(pw, memoryUse)
+ dumpNotificationViewUsage(pw, memoryUse)
+ }
+
+ /** Renders a table of notification object usage into passed [PrintWriter]. */
+ private fun dumpNotificationObjects(pw: PrintWriter, memoryUse: List<NotificationMemoryUsage>) {
+ pw.println("Notification Object Usage")
+ pw.println("-----------")
+ pw.println(
+ "Package".padEnd(35) +
+ "\t\tSmall\tLarge\t${"Style".padEnd(15)}\t\tStyle\tBig\tExtend.\tExtras\tCustom"
+ )
+ pw.println("".padEnd(35) + "\t\tIcon\tIcon\t${"".padEnd(15)}\t\tIcon\tPicture\t \t \tView")
+ pw.println()
+
+ memoryUse.forEach { use ->
+ pw.println(
+ use.packageName.padEnd(35) +
+ "\t\t" +
+ "${use.objectUsage.smallIcon}\t${use.objectUsage.largeIcon}\t" +
+ (styleEnumToString(use.objectUsage.style).take(15) ?: "").padEnd(15) +
+ "\t\t${use.objectUsage.styleIcon}\t" +
+ "${use.objectUsage.bigPicture}\t${use.objectUsage.extender}\t" +
+ "${use.objectUsage.extras}\t${use.objectUsage.hasCustomView}\t" +
+ use.notificationKey
+ )
+ }
+
+ // Calculate totals for easily glanceable summary.
+ data class Totals(
+ var smallIcon: Int = 0,
+ var largeIcon: Int = 0,
+ var styleIcon: Int = 0,
+ var bigPicture: Int = 0,
+ var extender: Int = 0,
+ var extras: Int = 0,
+ )
+
+ val totals =
+ memoryUse.fold(Totals()) { t, usage ->
+ t.smallIcon += usage.objectUsage.smallIcon
+ t.largeIcon += usage.objectUsage.largeIcon
+ t.styleIcon += usage.objectUsage.styleIcon
+ t.bigPicture += usage.objectUsage.bigPicture
+ t.extender += usage.objectUsage.extender
+ t.extras += usage.objectUsage.extras
+ t
+ }
+
+ pw.println()
+ pw.println("TOTALS")
+ pw.println(
+ "".padEnd(35) +
+ "\t\t" +
+ "${toKb(totals.smallIcon)}\t${toKb(totals.largeIcon)}\t" +
+ "".padEnd(15) +
+ "\t\t${toKb(totals.styleIcon)}\t" +
+ "${toKb(totals.bigPicture)}\t${toKb(totals.extender)}\t" +
+ toKb(totals.extras)
+ )
+ pw.println()
+ }
+
+ /** Renders a table of notification view usage into passed [PrintWriter] */
+ private fun dumpNotificationViewUsage(
+ pw: PrintWriter,
+ memoryUse: List<NotificationMemoryUsage>,
+ ) {
+
+ data class Totals(
+ var smallIcon: Int = 0,
+ var largeIcon: Int = 0,
+ var style: Int = 0,
+ var customViews: Int = 0,
+ var softwareBitmapsPenalty: Int = 0,
+ )
+
+ val totals = Totals()
+ pw.println("Notification View Usage")
+ pw.println("-----------")
+ pw.println("View Type".padEnd(24) + "\tSmall\tLarge\tStyle\tCustom\tSoftware")
+ pw.println("".padEnd(24) + "\tIcon\tIcon\tUse\tView\tBitmaps")
+ pw.println()
+ memoryUse
+ .filter { it.viewUsage.isNotEmpty() }
+ .forEach { use ->
+ pw.println(use.packageName + " " + use.notificationKey)
+ use.viewUsage.forEach { view ->
+ pw.println(
+ " ${view.viewType.toString().padEnd(24)}\t${view.smallIcon}" +
+ "\t${view.largeIcon}\t${view.style}" +
+ "\t${view.customViews}\t${view.softwareBitmapsPenalty}"
+ )
+
+ if (view.viewType == ViewType.TOTAL) {
+ totals.smallIcon += view.smallIcon
+ totals.largeIcon += view.largeIcon
+ totals.style += view.style
+ totals.customViews += view.customViews
+ totals.softwareBitmapsPenalty += view.softwareBitmapsPenalty
+ }
+ }
+ }
+ pw.println()
+ pw.println("TOTALS")
+ pw.println(
+ " ${"".padEnd(24)}\t${toKb(totals.smallIcon)}" +
+ "\t${toKb(totals.largeIcon)}\t${toKb(totals.style)}" +
+ "\t${toKb(totals.customViews)}\t${toKb(totals.softwareBitmapsPenalty)}"
+ )
+ pw.println()
+ }
+
+ private fun styleEnumToString(styleEnum: Int): String =
+ when (styleEnum) {
+ NotificationEnums.STYLE_UNSPECIFIED -> "Unspecified"
+ NotificationEnums.STYLE_NONE -> "None"
+ NotificationEnums.STYLE_BIG_PICTURE -> "BigPicture"
+ NotificationEnums.STYLE_BIG_TEXT -> "BigText"
+ NotificationEnums.STYLE_CALL -> "Call"
+ NotificationEnums.STYLE_DECORATED_CUSTOM_VIEW -> "DCustomView"
+ NotificationEnums.STYLE_INBOX -> "Inbox"
+ NotificationEnums.STYLE_MEDIA -> "Media"
+ NotificationEnums.STYLE_MESSAGING -> "Messaging"
+ NotificationEnums.STYLE_RANKER_GROUP -> "RankerGroup"
+ else -> "Unknown"
+ }
+
+ private fun toKb(bytes: Int): String {
+ return (bytes / 1024).toString() + " KB"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt
new file mode 100644
index 0000000..ec8501a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt
@@ -0,0 +1,194 @@
+/*
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.logging
+
+import android.app.StatsManager
+import android.util.StatsEvent
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.shared.system.SysUiStatsLog
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.util.traceSection
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import kotlin.math.roundToInt
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.runBlocking
+
+/** Periodically logs current state of notification memory consumption. */
+@SysUISingleton
+class NotificationMemoryLogger
+@Inject
+constructor(
+ private val notificationPipeline: NotifPipeline,
+ private val statsManager: StatsManager,
+ @Main private val mainDispatcher: CoroutineDispatcher,
+ @Background private val backgroundExecutor: Executor
+) : StatsManager.StatsPullAtomCallback {
+
+ /**
+ * This class is used to accumulate and aggregate data - the fields mirror values in statd Atom
+ * with ONE IMPORTANT difference - the values are in bytes, not KB!
+ */
+ internal data class NotificationMemoryUseAtomBuilder(val uid: Int, val style: Int) {
+ var count: Int = 0
+ var countWithInflatedViews: Int = 0
+ var smallIconObject: Int = 0
+ var smallIconBitmapCount: Int = 0
+ var largeIconObject: Int = 0
+ var largeIconBitmapCount: Int = 0
+ var bigPictureObject: Int = 0
+ var bigPictureBitmapCount: Int = 0
+ var extras: Int = 0
+ var extenders: Int = 0
+ var smallIconViews: Int = 0
+ var largeIconViews: Int = 0
+ var systemIconViews: Int = 0
+ var styleViews: Int = 0
+ var customViews: Int = 0
+ var softwareBitmaps: Int = 0
+ var seenCount = 0
+ }
+
+ fun init() {
+ statsManager.setPullAtomCallback(
+ SysUiStatsLog.NOTIFICATION_MEMORY_USE,
+ null,
+ backgroundExecutor,
+ this
+ )
+ }
+
+ /** Called by statsd to pull data. */
+ override fun onPullAtom(atomTag: Int, data: MutableList<StatsEvent>): Int =
+ traceSection("NML#onPullAtom") {
+ if (atomTag != SysUiStatsLog.NOTIFICATION_MEMORY_USE) {
+ return StatsManager.PULL_SKIP
+ }
+
+ // Notifications can only be retrieved on the main thread, so switch to that thread.
+ val notifications = getAllNotificationsOnMainThread()
+ val notificationMemoryUse =
+ NotificationMemoryMeter.notificationMemoryUse(notifications)
+ .sortedWith(
+ compareBy(
+ { it.packageName },
+ { it.objectUsage.style },
+ { it.notificationKey }
+ )
+ )
+ val usageData = aggregateMemoryUsageData(notificationMemoryUse)
+ usageData.forEach { (_, use) ->
+ data.add(
+ SysUiStatsLog.buildStatsEvent(
+ SysUiStatsLog.NOTIFICATION_MEMORY_USE,
+ use.uid,
+ use.style,
+ use.count,
+ use.countWithInflatedViews,
+ toKb(use.smallIconObject),
+ use.smallIconBitmapCount,
+ toKb(use.largeIconObject),
+ use.largeIconBitmapCount,
+ toKb(use.bigPictureObject),
+ use.bigPictureBitmapCount,
+ toKb(use.extras),
+ toKb(use.extenders),
+ toKb(use.smallIconViews),
+ toKb(use.largeIconViews),
+ toKb(use.systemIconViews),
+ toKb(use.styleViews),
+ toKb(use.customViews),
+ toKb(use.softwareBitmaps),
+ use.seenCount
+ )
+ )
+ }
+
+ return StatsManager.PULL_SUCCESS
+ }
+
+ private fun getAllNotificationsOnMainThread() =
+ runBlocking(mainDispatcher) {
+ traceSection("NML#getNotifications") { notificationPipeline.allNotifs }
+ }
+
+ /** Aggregates memory usage data by package and style, returning sums. */
+ private fun aggregateMemoryUsageData(
+ notificationMemoryUse: List<NotificationMemoryUsage>
+ ): Map<Pair<String, Int>, NotificationMemoryUseAtomBuilder> {
+ return notificationMemoryUse
+ .groupingBy { Pair(it.packageName, it.objectUsage.style) }
+ .aggregate {
+ _,
+ accumulator: NotificationMemoryUseAtomBuilder?,
+ element: NotificationMemoryUsage,
+ first ->
+ val use =
+ if (first) {
+ NotificationMemoryUseAtomBuilder(element.uid, element.objectUsage.style)
+ } else {
+ accumulator!!
+ }
+
+ use.count++
+ // If the views of the notification weren't inflated, the list of memory usage
+ // parameters will be empty.
+ if (element.viewUsage.isNotEmpty()) {
+ use.countWithInflatedViews++
+ }
+
+ use.smallIconObject += element.objectUsage.smallIcon
+ if (element.objectUsage.smallIcon > 0) {
+ use.smallIconBitmapCount++
+ }
+
+ use.largeIconObject += element.objectUsage.largeIcon
+ if (element.objectUsage.largeIcon > 0) {
+ use.largeIconBitmapCount++
+ }
+
+ use.bigPictureObject += element.objectUsage.bigPicture
+ if (element.objectUsage.bigPicture > 0) {
+ use.bigPictureBitmapCount++
+ }
+
+ use.extras += element.objectUsage.extras
+ use.extenders += element.objectUsage.extender
+
+ // Use totals count which are more accurate when aggregated
+ // in this manner.
+ element.viewUsage
+ .firstOrNull { vu -> vu.viewType == ViewType.TOTAL }
+ ?.let {
+ use.smallIconViews += it.smallIcon
+ use.largeIconViews += it.largeIcon
+ use.systemIconViews += it.systemIcons
+ use.styleViews += it.style
+ use.customViews += it.style
+ use.softwareBitmaps += it.softwareBitmapsPenalty
+ }
+
+ return@aggregate use
+ }
+ }
+
+ /** Rounds the passed value to the nearest KB - e.g. 700B rounds to 1KB. */
+ private fun toKb(value: Int): Int = (value.toFloat() / 1024f).roundToInt()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeter.kt
index 7d39e18..41fb91e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeter.kt
@@ -1,12 +1,20 @@
package com.android.systemui.statusbar.notification.logging
import android.app.Notification
+import android.app.Notification.BigPictureStyle
+import android.app.Notification.BigTextStyle
+import android.app.Notification.CallStyle
+import android.app.Notification.DecoratedCustomViewStyle
+import android.app.Notification.InboxStyle
+import android.app.Notification.MediaStyle
+import android.app.Notification.MessagingStyle
import android.app.Person
import android.graphics.Bitmap
import android.graphics.drawable.Icon
import android.os.Bundle
import android.os.Parcel
import android.os.Parcelable
+import android.stats.sysui.NotificationEnums
import androidx.annotation.WorkerThread
import com.android.systemui.statusbar.notification.NotificationUtils
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -19,6 +27,7 @@
private const val TV_EXTENSIONS = "android.tv.EXTENSIONS"
private const val WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS"
private const val WEARABLE_EXTENSIONS_BACKGROUND = "background"
+ private const val AUTOGROUP_KEY = "ranker_group"
/** Returns a list of memory use entries for currently shown notifications. */
@WorkerThread
@@ -29,12 +38,15 @@
.asSequence()
.map { entry ->
val packageName = entry.sbn.packageName
+ val uid = entry.sbn.uid
val notificationObjectUsage =
notificationMemoryUse(entry.sbn.notification, hashSetOf())
val notificationViewUsage = NotificationMemoryViewWalker.getViewUsage(entry.row)
NotificationMemoryUsage(
packageName,
+ uid,
NotificationUtils.logKey(entry.sbn.key),
+ entry.sbn.notification,
notificationObjectUsage,
notificationViewUsage
)
@@ -49,7 +61,9 @@
): NotificationMemoryUsage {
return NotificationMemoryUsage(
entry.sbn.packageName,
+ entry.sbn.uid,
NotificationUtils.logKey(entry.sbn.key),
+ entry.sbn.notification,
notificationMemoryUse(entry.sbn.notification, seenBitmaps),
NotificationMemoryViewWalker.getViewUsage(entry.row)
)
@@ -116,7 +130,13 @@
val wearExtenderBackground =
computeParcelableUse(wearExtender, WEARABLE_EXTENSIONS_BACKGROUND, seenBitmaps)
- val style = notification.notificationStyle
+ val style =
+ if (notification.group == AUTOGROUP_KEY) {
+ NotificationEnums.STYLE_RANKER_GROUP
+ } else {
+ styleEnum(notification.notificationStyle)
+ }
+
val hasCustomView = notification.contentView != null || notification.bigContentView != null
val extrasSize = computeBundleSize(extras)
@@ -124,7 +144,7 @@
smallIcon = smallIconUse,
largeIcon = largeIconUse,
extras = extrasSize,
- style = style?.simpleName,
+ style = style,
styleIcon =
bigPictureIconUse +
peopleUse +
@@ -144,6 +164,25 @@
}
/**
+ * Returns logging style enum based on current style class.
+ *
+ * @return style value in [NotificationEnums]
+ */
+ private fun styleEnum(style: Class<out Notification.Style>?): Int =
+ when (style?.name) {
+ null -> NotificationEnums.STYLE_NONE
+ BigTextStyle::class.java.name -> NotificationEnums.STYLE_BIG_TEXT
+ BigPictureStyle::class.java.name -> NotificationEnums.STYLE_BIG_PICTURE
+ InboxStyle::class.java.name -> NotificationEnums.STYLE_INBOX
+ MediaStyle::class.java.name -> NotificationEnums.STYLE_MEDIA
+ DecoratedCustomViewStyle::class.java.name ->
+ NotificationEnums.STYLE_DECORATED_CUSTOM_VIEW
+ MessagingStyle::class.java.name -> NotificationEnums.STYLE_MESSAGING
+ CallStyle::class.java.name -> NotificationEnums.STYLE_CALL
+ else -> NotificationEnums.STYLE_UNSPECIFIED
+ }
+
+ /**
* Calculates size of the bundle data (excluding FDs and other shared objects like ashmem
* bitmaps). Can be slow.
*/
@@ -176,7 +215,7 @@
*
* @return memory usage in bytes or 0 if the icon is Uri/Resource based
*/
- private fun computeIconUse(icon: Icon?, seenBitmaps: HashSet<Int>) =
+ private fun computeIconUse(icon: Icon?, seenBitmaps: HashSet<Int>): Int =
when (icon?.type) {
Icon.TYPE_BITMAP -> computeBitmapUse(icon.bitmap, seenBitmaps)
Icon.TYPE_ADAPTIVE_BITMAP -> computeBitmapUse(icon.bitmap, seenBitmaps)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitor.kt
index c09cc43..f38c1e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitor.kt
@@ -18,11 +18,10 @@
package com.android.systemui.statusbar.notification.logging
import android.util.Log
-import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.statusbar.notification.collection.NotifPipeline
-import java.io.PrintWriter
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import dagger.Lazy
import javax.inject.Inject
/** This class monitors and logs current Notification memory use. */
@@ -30,9 +29,10 @@
class NotificationMemoryMonitor
@Inject
constructor(
- val notificationPipeline: NotifPipeline,
- val dumpManager: DumpManager,
-) : Dumpable {
+ private val featureFlags: FeatureFlags,
+ private val notificationMemoryDumper: NotificationMemoryDumper,
+ private val notificationMemoryLogger: Lazy<NotificationMemoryLogger>,
+) {
companion object {
private const val TAG = "NotificationMemory"
@@ -40,127 +40,10 @@
fun init() {
Log.d(TAG, "NotificationMemoryMonitor initialized.")
- dumpManager.registerDumpable(javaClass.simpleName, this)
- }
-
- override fun dump(pw: PrintWriter, args: Array<out String>) {
- val memoryUse =
- NotificationMemoryMeter.notificationMemoryUse(notificationPipeline.allNotifs)
- .sortedWith(compareBy({ it.packageName }, { it.notificationKey }))
- dumpNotificationObjects(pw, memoryUse)
- dumpNotificationViewUsage(pw, memoryUse)
- }
-
- /** Renders a table of notification object usage into passed [PrintWriter]. */
- private fun dumpNotificationObjects(pw: PrintWriter, memoryUse: List<NotificationMemoryUsage>) {
- pw.println("Notification Object Usage")
- pw.println("-----------")
- pw.println(
- "Package".padEnd(35) +
- "\t\tSmall\tLarge\t${"Style".padEnd(15)}\t\tStyle\tBig\tExtend.\tExtras\tCustom"
- )
- pw.println("".padEnd(35) + "\t\tIcon\tIcon\t${"".padEnd(15)}\t\tIcon\tPicture\t \t \tView")
- pw.println()
-
- memoryUse.forEach { use ->
- pw.println(
- use.packageName.padEnd(35) +
- "\t\t" +
- "${use.objectUsage.smallIcon}\t${use.objectUsage.largeIcon}\t" +
- (use.objectUsage.style?.take(15) ?: "").padEnd(15) +
- "\t\t${use.objectUsage.styleIcon}\t" +
- "${use.objectUsage.bigPicture}\t${use.objectUsage.extender}\t" +
- "${use.objectUsage.extras}\t${use.objectUsage.hasCustomView}\t" +
- use.notificationKey
- )
+ notificationMemoryDumper.init()
+ if (featureFlags.isEnabled(Flags.NOTIFICATION_MEMORY_LOGGING_ENABLED)) {
+ Log.d(TAG, "Notification memory logging enabled.")
+ notificationMemoryLogger.get().init()
}
-
- // Calculate totals for easily glanceable summary.
- data class Totals(
- var smallIcon: Int = 0,
- var largeIcon: Int = 0,
- var styleIcon: Int = 0,
- var bigPicture: Int = 0,
- var extender: Int = 0,
- var extras: Int = 0,
- )
-
- val totals =
- memoryUse.fold(Totals()) { t, usage ->
- t.smallIcon += usage.objectUsage.smallIcon
- t.largeIcon += usage.objectUsage.largeIcon
- t.styleIcon += usage.objectUsage.styleIcon
- t.bigPicture += usage.objectUsage.bigPicture
- t.extender += usage.objectUsage.extender
- t.extras += usage.objectUsage.extras
- t
- }
-
- pw.println()
- pw.println("TOTALS")
- pw.println(
- "".padEnd(35) +
- "\t\t" +
- "${toKb(totals.smallIcon)}\t${toKb(totals.largeIcon)}\t" +
- "".padEnd(15) +
- "\t\t${toKb(totals.styleIcon)}\t" +
- "${toKb(totals.bigPicture)}\t${toKb(totals.extender)}\t" +
- toKb(totals.extras)
- )
- pw.println()
- }
-
- /** Renders a table of notification view usage into passed [PrintWriter] */
- private fun dumpNotificationViewUsage(
- pw: PrintWriter,
- memoryUse: List<NotificationMemoryUsage>,
- ) {
-
- data class Totals(
- var smallIcon: Int = 0,
- var largeIcon: Int = 0,
- var style: Int = 0,
- var customViews: Int = 0,
- var softwareBitmapsPenalty: Int = 0,
- )
-
- val totals = Totals()
- pw.println("Notification View Usage")
- pw.println("-----------")
- pw.println("View Type".padEnd(24) + "\tSmall\tLarge\tStyle\tCustom\tSoftware")
- pw.println("".padEnd(24) + "\tIcon\tIcon\tUse\tView\tBitmaps")
- pw.println()
- memoryUse
- .filter { it.viewUsage.isNotEmpty() }
- .forEach { use ->
- pw.println(use.packageName + " " + use.notificationKey)
- use.viewUsage.forEach { view ->
- pw.println(
- " ${view.viewType.toString().padEnd(24)}\t${view.smallIcon}" +
- "\t${view.largeIcon}\t${view.style}" +
- "\t${view.customViews}\t${view.softwareBitmapsPenalty}"
- )
-
- if (view.viewType == ViewType.TOTAL) {
- totals.smallIcon += view.smallIcon
- totals.largeIcon += view.largeIcon
- totals.style += view.style
- totals.customViews += view.customViews
- totals.softwareBitmapsPenalty += view.softwareBitmapsPenalty
- }
- }
- }
- pw.println()
- pw.println("TOTALS")
- pw.println(
- " ${"".padEnd(24)}\t${toKb(totals.smallIcon)}" +
- "\t${toKb(totals.largeIcon)}\t${toKb(totals.style)}" +
- "\t${toKb(totals.customViews)}\t${toKb(totals.softwareBitmapsPenalty)}"
- )
- pw.println()
- }
-
- private fun toKb(bytes: Int): String {
- return (bytes / 1024).toString() + " KB"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalker.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalker.kt
index a0bee15..2d04211 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalker.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalker.kt
@@ -50,7 +50,11 @@
/**
* Returns memory usage of public and private views contained in passed
- * [ExpandableNotificationRow]
+ * [ExpandableNotificationRow]. Each entry will correspond to one of the [ViewType] values with
+ * [ViewType.TOTAL] totalling all memory use. If a type of view is missing, the corresponding
+ * entry will not appear in resulting list.
+ *
+ * This will return an empty list if the ExpandableNotificationRow has no views inflated.
*/
fun getViewUsage(row: ExpandableNotificationRow?): List<NotificationViewUsage> {
if (row == null) {
@@ -58,42 +62,72 @@
}
// The ordering here is significant since it determines deduplication of seen drawables.
- return listOf(
- getViewUsage(ViewType.PRIVATE_EXPANDED_VIEW, row.privateLayout?.expandedChild),
- getViewUsage(ViewType.PRIVATE_CONTRACTED_VIEW, row.privateLayout?.contractedChild),
- getViewUsage(ViewType.PRIVATE_HEADS_UP_VIEW, row.privateLayout?.headsUpChild),
- getViewUsage(ViewType.PUBLIC_VIEW, row.publicLayout),
- getTotalUsage(row)
- )
+ val perViewUsages =
+ listOf(
+ getViewUsage(ViewType.PRIVATE_EXPANDED_VIEW, row.privateLayout?.expandedChild),
+ getViewUsage(
+ ViewType.PRIVATE_CONTRACTED_VIEW,
+ row.privateLayout?.contractedChild
+ ),
+ getViewUsage(ViewType.PRIVATE_HEADS_UP_VIEW, row.privateLayout?.headsUpChild),
+ getViewUsage(
+ ViewType.PUBLIC_VIEW,
+ row.publicLayout?.expandedChild,
+ row.publicLayout?.contractedChild,
+ row.publicLayout?.headsUpChild
+ ),
+ )
+ .filterNotNull()
+
+ return if (perViewUsages.isNotEmpty()) {
+ // Attach summed totals field only if there was any view actually measured.
+ // This reduces bug report noise and makes checks for collapsed views easier.
+ val totals = getTotalUsage(row)
+ if (totals == null) {
+ perViewUsages
+ } else {
+ perViewUsages + totals
+ }
+ } else {
+ listOf()
+ }
}
/**
* Calculate total usage of all views - we need to do a separate traversal to make sure we don't
* double count fields.
*/
- private fun getTotalUsage(row: ExpandableNotificationRow): NotificationViewUsage {
- val totalUsage = UsageBuilder()
+ private fun getTotalUsage(row: ExpandableNotificationRow): NotificationViewUsage? {
val seenObjects = hashSetOf<Int>()
-
- row.publicLayout?.let { computeViewHierarchyUse(it, totalUsage, seenObjects) }
- row.privateLayout?.let { child ->
- for (view in listOf(child.expandedChild, child.contractedChild, child.headsUpChild)) {
- (view as? ViewGroup)?.let { v ->
- computeViewHierarchyUse(v, totalUsage, seenObjects)
- }
- }
- }
- return totalUsage.build(ViewType.TOTAL)
+ return getViewUsage(
+ ViewType.TOTAL,
+ row.privateLayout?.expandedChild,
+ row.privateLayout?.contractedChild,
+ row.privateLayout?.headsUpChild,
+ row.publicLayout?.expandedChild,
+ row.publicLayout?.contractedChild,
+ row.publicLayout?.headsUpChild,
+ seenObjects = seenObjects
+ )
}
private fun getViewUsage(
type: ViewType,
- rootView: View?,
+ vararg rootViews: View?,
seenObjects: HashSet<Int> = hashSetOf()
- ): NotificationViewUsage {
- val usageBuilder = UsageBuilder()
- (rootView as? ViewGroup)?.let { computeViewHierarchyUse(it, usageBuilder, seenObjects) }
- return usageBuilder.build(type)
+ ): NotificationViewUsage? {
+ val usageBuilder = lazy { UsageBuilder() }
+ rootViews.forEach { rootView ->
+ (rootView as? ViewGroup)?.let { rootViewGroup ->
+ computeViewHierarchyUse(rootViewGroup, usageBuilder.value, seenObjects)
+ }
+ }
+
+ return if (usageBuilder.isInitialized()) {
+ usageBuilder.value.build(type)
+ } else {
+ null
+ }
}
private fun computeViewHierarchyUse(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index c7c1634..c1173e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -284,6 +284,7 @@
private View.OnClickListener mOnAppClickListener;
private View.OnClickListener mOnFeedbackClickListener;
private Path mExpandingClipPath;
+ private boolean mIsInlineReplyAnimationFlagEnabled = false;
// Listener will be called when receiving a long click event.
// Use #setLongPressPosition to optionally assign positional data with the long press.
@@ -976,10 +977,10 @@
/**
* Updates states of all children.
*/
- public void updateChildrenStates(AmbientState ambientState) {
+ public void updateChildrenStates() {
if (mIsSummaryWithChildren) {
ExpandableViewState parentState = getViewState();
- mChildrenContainer.updateState(parentState, ambientState);
+ mChildrenContainer.updateState(parentState);
}
}
@@ -2223,6 +2224,7 @@
if (mNotificationParent != null) {
mNotificationParent.setClipTopAmount(0);
}
+ setTranslationX(0);
return;
}
@@ -2241,6 +2243,7 @@
setTranslationZ(translationZ);
float extraWidthForClipping = params.getWidth() - getWidth();
setExtraWidthForClipping(extraWidthForClipping);
+
int top;
if (params.getStartRoundedTopClipping() > 0) {
// If we were clipping initially, let's interpolate from the start position to the
@@ -2248,20 +2251,22 @@
float expandProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
params.getProgress(0,
NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING));
- float startTop = params.getStartNotificationTop();
- top = (int) Math.min(MathUtils.lerp(startTop,
- params.getTop(), expandProgress),
+ int startTop = params.getStartNotificationTop();
+ top = (int) Math.min(MathUtils.lerp(startTop, params.getTop(), expandProgress),
startTop);
} else {
top = params.getTop();
}
int actualHeight = params.getBottom() - top;
setActualHeight(actualHeight);
+
+ int notificationStackTop = params.getNotificationParentTop();
+ top -= notificationStackTop;
int startClipTopAmount = params.getStartClipTopAmount();
int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, params.getProgress());
if (mNotificationParent != null) {
- float parentY = mNotificationParent.getTranslationY();
- top -= parentY;
+ float parentTranslationY = mNotificationParent.getTranslationY();
+ top -= parentTranslationY;
mNotificationParent.setTranslationZ(translationZ);
// When the expanding notification is below its parent, the parent must be clipped
@@ -2270,15 +2275,14 @@
// pixels to show the expanding notification, while still taking the decreasing
// notification clipTopAmount into consideration, so 'top + clipTopAmount'.
int parentStartClipTopAmount = params.getParentStartClipTopAmount();
- int parentClipTopAmount = Math.min(parentStartClipTopAmount,
- top + clipTopAmount);
+ int parentClipTopAmount = Math.min(parentStartClipTopAmount, top + clipTopAmount);
mNotificationParent.setClipTopAmount(parentClipTopAmount);
mNotificationParent.setExtraWidthForClipping(extraWidthForClipping);
- float clipBottom = Math.max(params.getBottom(),
- parentY + mNotificationParent.getActualHeight()
+ float clipBottom = Math.max(params.getBottom() - notificationStackTop,
+ parentTranslationY + mNotificationParent.getActualHeight()
- mNotificationParent.getClipBottomAmount());
- float clipTop = Math.min(params.getTop(), parentY);
+ float clipTop = Math.min(params.getTop() - notificationStackTop, parentTranslationY);
int minimumHeightForClipping = (int) (clipBottom - clipTop);
mNotificationParent.setMinimumHeightForClipping(minimumHeightForClipping);
} else if (startClipTopAmount != 0) {
@@ -2286,6 +2290,9 @@
}
setTranslationY(top);
+ float absoluteCenterX = getLocationOnScreen()[0] + getWidth() / 2f - getTranslationX();
+ setTranslationX(params.getCenterX() - absoluteCenterX);
+
final float maxRadius = getMaxRadius();
mTopRoundnessDuringLaunchAnimation = params.getTopCornerRadius() / maxRadius;
mBottomRoundnessDuringLaunchAnimation = params.getBottomCornerRadius() / maxRadius;
@@ -3073,6 +3080,10 @@
return 0;
}
+ public void setInlineReplyAnimationFlagEnabled(boolean isEnabled) {
+ mIsInlineReplyAnimationFlagEnabled = isEnabled;
+ }
+
@Override
public void setActualHeight(int height, boolean notifyListeners) {
boolean changed = height != getActualHeight();
@@ -3092,7 +3103,11 @@
}
int contentHeight = Math.max(getMinHeight(), height);
for (NotificationContentView l : mLayouts) {
- l.setContentHeight(contentHeight);
+ if (mIsInlineReplyAnimationFlagEnabled) {
+ l.setContentHeight(height);
+ } else {
+ l.setContentHeight(contentHeight);
+ }
}
if (mIsSummaryWithChildren) {
mChildrenContainer.setActualHeight(height);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index 0213b96..2041245 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -214,7 +214,11 @@
} else {
maxRadius = res.getDimensionPixelSize(R.dimen.notification_corner_radius);
}
- mRoundableState = new RoundableState(this, this, maxRadius);
+ if (mRoundableState == null) {
+ mRoundableState = new RoundableState(this, this, maxRadius);
+ } else {
+ mRoundableState.setMaxRadius(maxRadius);
+ }
setClipToOutline(mAlwaysRoundBothCorners);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 277ad8e..e46bf52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -70,7 +70,7 @@
/**
* A frame layout containing the actual payload of the notification, including the contracted,
- * expanded and heads up layout. This class is responsible for clipping the content and and
+ * expanded and heads up layout. This class is responsible for clipping the content and
* switching between the expanded, contracted and the heads up view depending on its clipped size.
*/
public class NotificationContentView extends FrameLayout implements NotificationFadeAware {
@@ -627,6 +627,13 @@
int hint;
if (mHeadsUpChild != null && isVisibleOrTransitioning(VISIBLE_TYPE_HEADSUP)) {
hint = getViewHeight(VISIBLE_TYPE_HEADSUP);
+ if (mHeadsUpRemoteInput != null && mHeadsUpRemoteInput.isAnimatingAppearance()
+ && mHeadsUpRemoteInputController.isFocusAnimationFlagActive()) {
+ // While the RemoteInputView is animating its appearance, it should be allowed
+ // to overlap the hint, therefore no space is reserved for the hint during the
+ // appearance animation of the RemoteInputView
+ hint = 0;
+ }
} else if (mExpandedChild != null) {
hint = getViewHeight(VISIBLE_TYPE_EXPANDED);
} else if (mContractedChild != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 4a8e2db..4d1451e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -616,9 +616,8 @@
* Update the state of all its children based on a linear layout algorithm.
*
* @param parentState the state of the parent
- * @param ambientState the ambient state containing ambient information
*/
- public void updateState(ExpandableViewState parentState, AmbientState ambientState) {
+ public void updateState(ExpandableViewState parentState) {
int childCount = mAttachedChildren.size();
int yPosition = mNotificationHeaderMargin + mCurrentHeaderTranslation;
boolean firstChild = true;
@@ -661,9 +660,17 @@
childState.height = intrinsicHeight;
childState.setYTranslation(yPosition + launchTransitionCompensation);
childState.hidden = false;
- // When the group is expanded, the children cast the shadows rather than the parent
- // so use the parent's elevation here.
- if (childrenExpandedAndNotAnimating && mEnableShadowOnChildNotifications) {
+ if (child.isExpandAnimationRunning() || mContainingNotification.hasExpandingChild()) {
+ // Not modifying translationZ during launch animation. The translationZ of the
+ // expanding child is handled inside ExpandableNotificationRow and the translationZ
+ // of the other children inside the group should remain unchanged. In particular,
+ // they should not take over the translationZ of the parent, since the parent has
+ // a positive translationZ set only for the expanding child to be drawn above other
+ // notifications.
+ childState.setZTranslation(child.getTranslationZ());
+ } else if (childrenExpandedAndNotAnimating && mEnableShadowOnChildNotifications) {
+ // When the group is expanded, the children cast the shadows rather than the parent
+ // so use the parent's elevation here.
childState.setZTranslation(parentState.getZTranslation());
} else {
childState.setZTranslation(0);
@@ -716,9 +723,15 @@
mHeaderViewState = new ViewState();
}
mHeaderViewState.initFrom(mNotificationHeader);
- mHeaderViewState.setZTranslation(childrenExpandedAndNotAnimating
- ? parentState.getZTranslation()
- : 0);
+
+ if (mContainingNotification.hasExpandingChild()) {
+ // Not modifying translationZ during expand animation.
+ mHeaderViewState.setZTranslation(mNotificationHeader.getTranslationZ());
+ } else if (childrenExpandedAndNotAnimating) {
+ mHeaderViewState.setZTranslation(parentState.getZTranslation());
+ } else {
+ mHeaderViewState.setZTranslation(0);
+ }
mHeaderViewState.setYTranslation(mCurrentHeaderTranslation);
mHeaderViewState.setAlpha(mHeaderVisibleAmount);
// The hiding is done automatically by the alpha, otherwise we'll pick it up again
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 21e2bd8..ca1e397 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -146,7 +146,8 @@
private static final int DELAY_BEFORE_SHADE_CLOSE = 200;
private boolean mShadeNeedsToClose = false;
- private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
+ @VisibleForTesting
+ static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f;
private static final float RUBBER_BAND_FACTOR_ON_PANEL_EXPAND = 0.21f;
/**
@@ -1326,8 +1327,11 @@
* @param listenerNeedsAnimation does the listener need to animate?
*/
private void updateStackPosition(boolean listenerNeedsAnimation) {
+ float topOverscrollAmount = mShouldUseSplitNotificationShade
+ ? getCurrentOverScrollAmount(true /* top */) : 0f;
final float endTopPosition = mTopPadding + mExtraTopInsetForFullShadeTransition
+ mAmbientState.getOverExpansion()
+ + topOverscrollAmount
- getCurrentOverScrollAmount(false /* top */);
float fraction = mAmbientState.getExpansionFraction();
// If we are on quick settings, we need to quickly hide it to show the bouncer to avoid an
@@ -2613,8 +2617,10 @@
float bottomAmount = getCurrentOverScrollAmount(false);
if (velocityY < 0 && topAmount > 0) {
setOwnScrollY(mOwnScrollY - (int) topAmount);
- mDontReportNextOverScroll = true;
- setOverScrollAmount(0, true, false);
+ if (!mShouldUseSplitNotificationShade) {
+ mDontReportNextOverScroll = true;
+ setOverScrollAmount(0, true, false);
+ }
mMaxOverScroll = Math.abs(velocityY) / 1000f * getRubberBandFactor(true /* onTop */)
* mOverflingDistance + topAmount;
} else if (velocityY > 0 && bottomAmount > 0) {
@@ -2648,6 +2654,7 @@
float topOverScroll = getCurrentOverScrollAmount(true);
return mScrolledToTopOnFirstDown
&& !mExpandedInThisMotion
+ && !mShouldUseSplitNotificationShade
&& (initialVelocity > mMinimumVelocity
|| (topOverScroll > mMinTopOverScrollToEscape && initialVelocity > 0));
}
@@ -2713,7 +2720,7 @@
return RUBBER_BAND_FACTOR_AFTER_EXPAND;
} else if (mIsExpansionChanging || mPanelTracking) {
return RUBBER_BAND_FACTOR_ON_PANEL_EXPAND;
- } else if (mScrolledToTopOnFirstDown) {
+ } else if (mScrolledToTopOnFirstDown && !mShouldUseSplitNotificationShade) {
return 1.0f;
}
return RUBBER_BAND_FACTOR_NORMAL;
@@ -3707,7 +3714,7 @@
* of DisplayArea into relative coordinates for all windows, we need to correct the
* QS Head bounds here.
*/
- final int xOffset = Math.round(ev.getRawX() - ev.getX());
+ final int xOffset = Math.round(ev.getRawX() - ev.getX() + mQsHeader.getLeft());
final int yOffset = Math.round(ev.getRawY() - ev.getY());
mQsHeaderBound.offsetTo(xOffset, yOffset);
return mQsHeaderBound.contains((int) ev.getRawX(), (int) ev.getRawY());
@@ -5705,7 +5712,8 @@
}
}
- private void updateSplitNotificationShade() {
+ @VisibleForTesting
+ void updateSplitNotificationShade() {
boolean split = LargeScreenUtils.shouldUseSplitNotificationShade(getResources());
if (split != mShouldUseSplitNotificationShade) {
mShouldUseSplitNotificationShade = split;
@@ -5772,14 +5780,20 @@
|| mExpandingNotificationRow == null) {
return;
}
- int left = Math.min(mLaunchAnimationParams.getLeft(), mRoundedRectClippingLeft);
- int right = Math.max(mLaunchAnimationParams.getRight(), mRoundedRectClippingRight);
- int bottom = Math.max(mLaunchAnimationParams.getBottom(), mRoundedRectClippingBottom);
+ int[] absoluteCoords = new int[2];
+ getLocationOnScreen(absoluteCoords);
+
+ int left = Math.min(mLaunchAnimationParams.getLeft() - absoluteCoords[0],
+ mRoundedRectClippingLeft);
+ int right = Math.max(mLaunchAnimationParams.getRight() - absoluteCoords[0],
+ mRoundedRectClippingRight);
+ int bottom = Math.max(mLaunchAnimationParams.getBottom() - absoluteCoords[1],
+ mRoundedRectClippingBottom);
float expandProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
mLaunchAnimationParams.getProgress(0,
NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING));
int top = (int) Math.min(MathUtils.lerp(mRoundedRectClippingTop,
- mLaunchAnimationParams.getTop(), expandProgress),
+ mLaunchAnimationParams.getTop() - absoluteCoords[1], expandProgress),
mRoundedRectClippingTop);
float topRadius = mLaunchAnimationParams.getTopCornerRadius();
float bottomRadius = mLaunchAnimationParams.getBottomCornerRadius();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index aff7b4c..6e63960 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -128,7 +128,7 @@
updateSpeedBumpState(algorithmState, speedBumpIndex);
updateShelfState(algorithmState, ambientState);
updateAlphaState(algorithmState, ambientState);
- getNotificationChildrenStates(algorithmState, ambientState);
+ getNotificationChildrenStates(algorithmState);
}
private void updateAlphaState(StackScrollAlgorithmState algorithmState,
@@ -231,14 +231,13 @@
}
}
- private void getNotificationChildrenStates(StackScrollAlgorithmState algorithmState,
- AmbientState ambientState) {
+ private void getNotificationChildrenStates(StackScrollAlgorithmState algorithmState) {
int childCount = algorithmState.visibleChildren.size();
for (int i = 0; i < childCount; i++) {
ExpandableView v = algorithmState.visibleChildren.get(i);
if (v instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) v;
- row.updateChildrenStates(ambientState);
+ row.updateChildrenStates();
}
}
}
@@ -871,8 +870,7 @@
}
for (int i = childCount - 1; i >= 0; i--) {
- childrenOnTop = updateChildZValue(i, childrenOnTop,
- algorithmState, ambientState, i == topHunIndex);
+ updateChildZValue(i, algorithmState, ambientState, i == topHunIndex);
}
}
@@ -882,15 +880,11 @@
*
* @param isTopHun Whether the child is a top HUN. A top HUN means a HUN that shows on the
* vertically top of screen. Top HUNs should have drop shadows
- * @param childrenOnTop It is greater than 0 when there's an existing HUN that is elevated
- * @return childrenOnTop The decimal part represents the fraction of the elevated HUN's height
- * that overlaps with QQS Panel. The integer part represents the count of
- * previous HUNs whose Z positions are greater than 0.
*/
- protected float updateChildZValue(int i, float childrenOnTop,
- StackScrollAlgorithmState algorithmState,
- AmbientState ambientState,
- boolean isTopHun) {
+ protected void updateChildZValue(int i,
+ StackScrollAlgorithmState algorithmState,
+ AmbientState ambientState,
+ boolean isTopHun) {
ExpandableView child = algorithmState.visibleChildren.get(i);
ExpandableViewState childViewState = child.getViewState();
float baseZ = ambientState.getBaseZHeight();
@@ -904,22 +898,16 @@
// Handles HUN shadow when Shade is opened, and AmbientState.mScrollY > 0
// Calculate the HUN's z-value based on its overlapping fraction with QQS Panel.
// When scrolling down shade to make HUN back to in-position in Notification Panel,
- // The over-lapping fraction goes to 0, and shadows hides gradually.
- if (childrenOnTop != 0.0f) {
- // To elevate the later HUN over previous HUN
- childrenOnTop++;
- } else {
- float overlap = ambientState.getTopPadding()
- + ambientState.getStackTranslation() - childViewState.getYTranslation();
- // To prevent over-shadow during HUN entry
- childrenOnTop += Math.min(
- 1.0f,
- overlap / childViewState.height
- );
- MathUtils.saturate(childrenOnTop);
+ // the overlapFraction goes to 0, and the pinned HUN's shadows hides gradually.
+ float overlap = ambientState.getTopPadding()
+ + ambientState.getStackTranslation() - childViewState.getYTranslation();
+
+ if (childViewState.height > 0) { // To avoid 0/0 problems
+ // To prevent over-shadow
+ float overlapFraction = MathUtils.saturate(overlap / childViewState.height);
+ childViewState.setZTranslation(baseZ
+ + overlapFraction * mPinnedZTranslationExtra);
}
- childViewState.setZTranslation(baseZ
- + childrenOnTop * mPinnedZTranslationExtra);
} else if (isTopHun) {
// In case this is a new view that has never been measured before, we don't want to
// elevate if we are currently expanded more than the notification
@@ -947,15 +935,14 @@
}
// Handles HUN shadow when shade is closed.
- // While HUN is showing and Shade is closed: headerVisibleAmount stays 0, shadow stays.
+ // While shade is closed, and during HUN's entry: headerVisibleAmount stays 0, shadow stays.
+ // While shade is closed, and HUN is showing: headerVisibleAmount stays 0, shadow stays.
// During HUN-to-Shade (eg. dragging down HUN to open Shade): headerVisibleAmount goes
// gradually from 0 to 1, shadow hides gradually.
// Header visibility is a deprecated concept, we are using headerVisibleAmount only because
// this value nicely goes from 0 to 1 during the HUN-to-Shade process.
-
childViewState.setZTranslation(childViewState.getZTranslation()
+ (1.0f - child.getHeaderVisibleAmount()) * mPinnedZTranslationExtra);
- return childrenOnTop;
}
public void setIsExpanded(boolean isExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 31cdb05..1fcfe4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
+import static android.app.StatusBarManager.DISABLE_HOME;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.WindowVisibleState;
@@ -34,6 +35,7 @@
import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
+import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
@@ -70,6 +72,7 @@
import android.hardware.devicestate.DeviceStateManager;
import android.metrics.LogMaker;
import android.net.Uri;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -1047,8 +1050,21 @@
// set the initial view visibility
int disabledFlags1 = result.mDisabledFlags1;
int disabledFlags2 = result.mDisabledFlags2;
- mInitController.addPostInitTask(
- () -> setUpDisableFlags(disabledFlags1, disabledFlags2));
+ mInitController.addPostInitTask(() -> {
+ setUpDisableFlags(disabledFlags1, disabledFlags2);
+ try {
+ // NOTE(b/262059863): Force-update the disable flags after applying the flags
+ // returned from registerStatusBar(). The result's disabled flags may be stale
+ // if StatusBarManager's disabled flags are updated between registering the bar and
+ // this handling this post-init task. We force an update in this case, and use a new
+ // token to not conflict with any other disabled flags already requested by SysUI
+ Binder token = new Binder();
+ mBarService.disable(DISABLE_HOME, token, mContext.getPackageName());
+ mBarService.disable(0, token, mContext.getPackageName());
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ });
mFalsingManager.addFalsingBeliefListener(mFalsingBeliefListener);
@@ -1132,10 +1148,9 @@
private void onFoldedStateChangedInternal(boolean isFolded, boolean willGoToSleep) {
// Folded state changes are followed by a screen off event.
// By default turning off the screen also closes the shade.
- // We want to make sure that the shade status is kept after
- // folding/unfolding.
- boolean isShadeOpen = mShadeController.isShadeOpen();
- boolean leaveOpen = isShadeOpen && !willGoToSleep;
+ // We want to make sure that the shade status is kept after folding/unfolding.
+ boolean isShadeOpen = mShadeController.isShadeFullyOpen();
+ boolean leaveOpen = isShadeOpen && !willGoToSleep && mState == SHADE;
if (DEBUG) {
Log.d(TAG, String.format(
"#onFoldedStateChanged(): "
@@ -1146,18 +1161,17 @@
isFolded, willGoToSleep, isShadeOpen, leaveOpen));
}
if (leaveOpen) {
- if (mKeyguardStateController.isShowing()) {
- // When device state changes on keyguard we don't want to keep the state of
- // the shade and instead we open clean state of keyguard with shade closed.
- // Normally some parts of QS state (like expanded/collapsed) are persisted and
- // that causes incorrect UI rendering, especially when changing state with QS
- // expanded. To prevent that we can close QS which resets QS and some parts of
- // the shade to its default state. Read more in b/201537421
- mCloseQsBeforeScreenOff = true;
- } else {
- // below makes shade stay open when going from folded to unfolded
- mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
- }
+ // below makes shade stay open when going from folded to unfolded
+ mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+ }
+ if (mState != SHADE && isShadeOpen) {
+ // When device state changes on KEYGUARD/SHADE_LOCKED we don't want to keep the state of
+ // the shade and instead we open clean state of keyguard with shade closed.
+ // Normally some parts of QS state (like expanded/collapsed) are persisted and
+ // that causes incorrect UI rendering, especially when changing state with QS
+ // expanded. To prevent that we can close QS which resets QS and some parts of
+ // the shade to its default state. Read more in b/201537421
+ mCloseQsBeforeScreenOff = true;
}
}
@@ -3559,7 +3573,7 @@
final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
@Override
- public void onScreenTurningOn(Runnable onDrawn) {
+ public void onScreenTurningOn() {
mFalsingCollector.onScreenTurningOn();
mNotificationPanelViewController.onScreenTurningOn();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
index 78b28d2..2ce1163 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
@@ -23,7 +23,7 @@
import android.view.ViewPropertyAnimator
import android.view.WindowInsets
import android.widget.FrameLayout
-import com.android.keyguard.KeyguardUpdateMonitor
+import androidx.annotation.StringRes
import com.android.keyguard.LockIconViewController
import com.android.systemui.R
import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder
@@ -51,21 +51,29 @@
defStyleRes,
) {
+ interface MessageDisplayer {
+ fun display(@StringRes stringResourceId: Int)
+ }
+
private var ambientIndicationArea: View? = null
private lateinit var binding: KeyguardBottomAreaViewBinder.Binding
- private lateinit var lockIconViewController: LockIconViewController
+ private var lockIconViewController: LockIconViewController? = null
/** Initializes the view. */
fun init(
viewModel: KeyguardBottomAreaViewModel,
- falsingManager: FalsingManager,
- lockIconViewController: LockIconViewController,
+ falsingManager: FalsingManager? = null,
+ lockIconViewController: LockIconViewController? = null,
+ messageDisplayer: MessageDisplayer? = null,
) {
- binding = bind(
+ binding =
+ bind(
this,
viewModel,
falsingManager,
- )
+ ) {
+ messageDisplayer?.display(it)
+ }
this.lockIconViewController = lockIconViewController
}
@@ -129,21 +137,21 @@
findViewById<View>(R.id.ambient_indication_container)?.let {
val (ambientLeft, ambientTop) = it.locationOnScreen
if (binding.shouldConstrainToTopOfLockIcon()) {
- //make top of ambient indication view the bottom of the lock icon
+ // make top of ambient indication view the bottom of the lock icon
it.layout(
- ambientLeft,
- lockIconViewController.bottom.toInt(),
- right - ambientLeft,
- ambientTop + it.measuredHeight
+ ambientLeft,
+ lockIconViewController?.bottom?.toInt() ?: 0,
+ right - ambientLeft,
+ ambientTop + it.measuredHeight
)
} else {
- //make bottom of ambient indication view the top of the lock icon
- val lockLocationTop = lockIconViewController.top
+ // make bottom of ambient indication view the top of the lock icon
+ val lockLocationTop = lockIconViewController?.top ?: 0
it.layout(
- ambientLeft,
- lockLocationTop.toInt() - it.measuredHeight,
- right - ambientLeft,
- lockLocationTop.toInt()
+ ambientLeft,
+ lockLocationTop.toInt() - it.measuredHeight,
+ right - ambientLeft,
+ lockLocationTop.toInt()
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index e70c81d..85590fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -11,6 +11,7 @@
import android.view.View;
import android.widget.FrameLayout;
+import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.collection.ArrayMap;
@@ -62,6 +63,8 @@
public static final String HIGH_PRIORITY = "high_priority";
private static final long AOD_ICONS_APPEAR_DURATION = 200;
+ @ColorInt
+ private static final int DEFAULT_AOD_ICON_COLOR = 0xffffffff;
private final ContrastColorUtil mContrastColorUtil;
private final Runnable mUpdateStatusBarIcons = this::updateStatusBarIcons;
@@ -84,7 +87,7 @@
private NotificationIconContainer mShelfIcons;
private NotificationIconContainer mAodIcons;
private final ArrayList<Rect> mTintAreas = new ArrayList<>();
- private Context mContext;
+ private final Context mContext;
private final DemoModeController mDemoModeController;
@@ -567,7 +570,7 @@
private void reloadAodColor() {
mAodIconTint = Utils.getColorAttrDefaultColor(mContext,
- R.attr.wallpaperTextColor);
+ R.attr.wallpaperTextColor, DEFAULT_AOD_ICON_COLOR);
}
private void updateAodIconColors() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 05bf860..be6e0cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -50,6 +50,8 @@
import com.android.systemui.EventLogTags;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.ShadeController;
@@ -106,6 +108,7 @@
private final LockPatternUtils mLockPatternUtils;
private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback;
private final ActivityIntentHelper mActivityIntentHelper;
+ private final FeatureFlags mFeatureFlags;
private final MetricsLogger mMetricsLogger;
private final StatusBarNotificationActivityStarterLogger mLogger;
@@ -149,7 +152,8 @@
NotificationPanelViewController panel,
ActivityLaunchAnimator activityLaunchAnimator,
NotificationLaunchAnimatorControllerProvider notificationAnimationProvider,
- LaunchFullScreenIntentProvider launchFullScreenIntentProvider) {
+ LaunchFullScreenIntentProvider launchFullScreenIntentProvider,
+ FeatureFlags featureFlags) {
mContext = context;
mMainThreadHandler = mainThreadHandler;
mUiBgExecutor = uiBgExecutor;
@@ -170,6 +174,7 @@
mLockPatternUtils = lockPatternUtils;
mStatusBarRemoteInputCallback = remoteInputCallback;
mActivityIntentHelper = activityIntentHelper;
+ mFeatureFlags = featureFlags;
mMetricsLogger = metricsLogger;
mLogger = logger;
mOnUserInteractionCallback = onUserInteractionCallback;
@@ -548,7 +553,10 @@
mLogger.logFullScreenIntentSuppressedByVR(entry);
return;
}
-
+ if (mFeatureFlags.isEnabled(Flags.FSI_CHROME)) {
+ // FsiChromeRepo runs its own implementation of launchFullScreenIntent
+ return;
+ }
// Stop screensaver if the notification has a fullscreen intent.
// (like an incoming phone call)
mUiBgExecutor.execute(() -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt
index 1d00c33..a6b04e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt
@@ -41,6 +41,7 @@
data class MobileConnectionModel(
/** From [ServiceStateListener.onServiceStateChanged] */
val isEmergencyOnly: Boolean = false,
+ val isRoaming: Boolean = false,
/** From [SignalStrengthsListener.onSignalStrengthsChanged] */
val isGsm: Boolean = false,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
index 2621f997..fc59f6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
@@ -50,4 +50,12 @@
* [SubscriptionManager.getDefaultDataSubscriptionId]
*/
val isDefaultDataSubscription: StateFlow<Boolean>
+
+ /**
+ * See [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber]. This bit only matters if
+ * the connection type is CDMA.
+ *
+ * True if the Enhanced Roaming Indicator (ERI) display number is not [TelephonyManager.ERI_OFF]
+ */
+ val cdmaRoaming: StateFlow<Boolean>
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
index aea85eb..498c0b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
@@ -17,8 +17,11 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository
import android.provider.Settings
+import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionManager
import com.android.settingslib.SignalIcon.MobileIconGroup
+import com.android.settingslib.mobile.MobileMappings
+import com.android.settingslib.mobile.MobileMappings.Config
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import kotlinx.coroutines.flow.Flow
@@ -47,6 +50,18 @@
/** Observe changes to the [Settings.Global.MOBILE_DATA] setting */
val globalMobileDataSettingChangedEvent: Flow<Unit>
+ /**
+ * [Config] is an object that tracks relevant configuration flags for a given subscription ID.
+ * In the case of [MobileMappings], it's hard-coded to check the default data subscription's
+ * config, so this will apply to every icon that we care about.
+ *
+ * Relevant bits in the config are things like
+ * [CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL]
+ *
+ * This flow will produce whenever the default data subscription or the carrier config changes.
+ */
+ val defaultDataSubRatConfig: StateFlow<Config>
+
/** The icon mapping from network type to [MobileIconGroup] for the default subscription */
val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
index d8e0e81..db9d24f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
@@ -19,6 +19,7 @@
import android.os.Bundle
import androidx.annotation.VisibleForTesting
import com.android.settingslib.SignalIcon
+import com.android.settingslib.mobile.MobileMappings
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.demomode.DemoMode
@@ -123,6 +124,15 @@
realRepository.activeMobileDataSubscriptionId.value
)
+ override val defaultDataSubRatConfig: StateFlow<MobileMappings.Config> =
+ activeRepo
+ .flatMapLatest { it.defaultDataSubRatConfig }
+ .stateIn(
+ scope,
+ SharingStarted.WhileSubscribed(),
+ realRepository.defaultDataSubRatConfig.value
+ )
+
override val defaultMobileIconMapping: Flow<Map<String, SignalIcon.MobileIconGroup>> =
activeRepo.flatMapLatest { it.defaultMobileIconMapping }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
index 1e7fae7..98b47e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
@@ -106,7 +106,8 @@
)
/** Demo mode doesn't currently support modifications to the mobile mappings */
- val defaultDataSubRatConfig = MutableStateFlow(MobileMappings.Config.readConfig(context))
+ override val defaultDataSubRatConfig =
+ MutableStateFlow(MobileMappings.Config.readConfig(context))
override val defaultMobileIconGroup = flowOf(TelephonyIcons.THREE_G)
@@ -185,6 +186,7 @@
connection.dataEnabled.value = true
connection.isDefaultDataSubscription.value = state.dataType != null
+ connection.cdmaRoaming.value = state.roaming
connection.connectionInfo.value = state.toMobileConnectionModel()
}
@@ -228,6 +230,7 @@
private fun Mobile.toMobileConnectionModel(): MobileConnectionModel {
return MobileConnectionModel(
isEmergencyOnly = false, // TODO(b/261029387): not yet supported
+ isRoaming = roaming,
isGsm = false, // TODO(b/261029387): not yet supported
cdmaLevel = level ?: 0,
primaryLevel = level ?: 0,
@@ -259,4 +262,6 @@
override val dataEnabled = MutableStateFlow(true)
override val isDefaultDataSubscription = MutableStateFlow(true)
+
+ override val cdmaRoaming = MutableStateFlow(false)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoModeMobileConnectionDataSource.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoModeMobileConnectionDataSource.kt
index da55787..2cdbc19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoModeMobileConnectionDataSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoModeMobileConnectionDataSource.kt
@@ -98,6 +98,7 @@
val inflateStrength = getString("inflate")?.toBoolean()
val activity = getString("activity")?.toActivity()
val carrierNetworkChange = getString("carriernetworkchange") == "show"
+ val roaming = getString("roam") == "show"
return Mobile(
level = level,
@@ -107,6 +108,7 @@
inflateStrength = inflateStrength,
activity = activity,
carrierNetworkChange = carrierNetworkChange,
+ roaming = roaming,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/model/FakeNetworkEventModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/model/FakeNetworkEventModel.kt
index 3f3acaf..b8543ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/model/FakeNetworkEventModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/model/FakeNetworkEventModel.kt
@@ -34,6 +34,7 @@
val inflateStrength: Boolean?,
@DataActivityType val activity: Int?,
val carrierNetworkChange: Boolean,
+ val roaming: Boolean,
) : FakeNetworkEventModel
data class MobileDisabled(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index 15505fd..295e0dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -27,6 +27,7 @@
import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE
import android.telephony.TelephonyManager
+import android.telephony.TelephonyManager.ERI_OFF
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.qualifiers.Application
@@ -95,7 +96,11 @@
TelephonyCallback.CarrierNetworkListener,
TelephonyCallback.DisplayInfoListener {
override fun onServiceStateChanged(serviceState: ServiceState) {
- state = state.copy(isEmergencyOnly = serviceState.isEmergencyOnly)
+ state =
+ state.copy(
+ isEmergencyOnly = serviceState.isEmergencyOnly,
+ isRoaming = serviceState.roaming,
+ )
trySend(state)
}
@@ -208,6 +213,11 @@
globalMobileDataSettingChangedEvent,
)
+ override val cdmaRoaming: StateFlow<Boolean> =
+ telephonyPollingEvent
+ .mapLatest { telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber != ERI_OFF }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
override val dataEnabled: StateFlow<Boolean> =
telephonyPollingEvent
.mapLatest { dataConnectionAllowed() }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index f27a9c9..483df47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -37,7 +37,6 @@
import androidx.annotation.VisibleForTesting
import com.android.internal.telephony.PhoneConstants
import com.android.settingslib.SignalIcon.MobileIconGroup
-import com.android.settingslib.mobile.MobileMappings
import com.android.settingslib.mobile.MobileMappings.Config
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -152,17 +151,7 @@
IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
)
- /**
- * [Config] is an object that tracks relevant configuration flags for a given subscription ID.
- * In the case of [MobileMappings], it's hard-coded to check the default data subscription's
- * config, so this will apply to every icon that we care about.
- *
- * Relevant bits in the config are things like
- * [CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL]
- *
- * This flow will produce whenever the default data subscription or the carrier config changes.
- */
- private val defaultDataSubRatConfig: StateFlow<Config> =
+ override val defaultDataSubRatConfig: StateFlow<Config> =
merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent)
.mapLatest { Config.readConfig(context) }
.stateIn(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index 8e1197c..15b70f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -45,12 +45,22 @@
/** Observable for the data enabled state of this connection */
val isDataEnabled: StateFlow<Boolean>
+ /** True if the RAT icon should always be displayed and false otherwise. */
+ val alwaysShowDataRatIcon: StateFlow<Boolean>
+
/** Observable for RAT type (network type) indicator */
val networkTypeIconGroup: StateFlow<MobileIconGroup>
/** True if this line of service is emergency-only */
val isEmergencyOnly: StateFlow<Boolean>
+ /**
+ * True if this connection is considered roaming. The roaming bit can come from [ServiceState],
+ * or directly from the telephony manager's CDMA ERI number value. Note that we don't consider a
+ * connection to be roaming while carrier network change is active
+ */
+ val isRoaming: StateFlow<Boolean>
+
/** Int describing the connection strength. 0-4 OR 1-5. See [numberOfLevels] */
val level: StateFlow<Int>
@@ -64,6 +74,7 @@
class MobileIconInteractorImpl(
@Application scope: CoroutineScope,
defaultSubscriptionHasDataEnabled: StateFlow<Boolean>,
+ override val alwaysShowDataRatIcon: StateFlow<Boolean>,
defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>,
defaultMobileIconGroup: StateFlow<MobileIconGroup>,
override val isDefaultConnectionFailed: StateFlow<Boolean>,
@@ -91,6 +102,18 @@
.mapLatest { it.isEmergencyOnly }
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
+ override val isRoaming: StateFlow<Boolean> =
+ combine(connectionInfo, connectionRepository.cdmaRoaming) { connection, cdmaRoaming ->
+ if (connection.carrierNetworkChangeActive) {
+ false
+ } else if (connection.isGsm) {
+ connection.isRoaming
+ } else {
+ cdmaRoaming
+ }
+ }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
override val level: StateFlow<Int> =
connectionInfo
.mapLatest { connection ->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
index 6f8fb2e..21f6d8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
@@ -55,6 +55,8 @@
val filteredSubscriptions: Flow<List<SubscriptionModel>>
/** True if the active mobile data subscription has data enabled */
val activeDataConnectionHasDataEnabled: StateFlow<Boolean>
+ /** True if the RAT icon should always be displayed and false otherwise. */
+ val alwaysShowDataRatIcon: StateFlow<Boolean>
/** The icon mapping from network type to [MobileIconGroup] for the default subscription */
val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>
/** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */
@@ -158,6 +160,11 @@
initialValue = mapOf()
)
+ override val alwaysShowDataRatIcon: StateFlow<Boolean> =
+ mobileConnectionsRepo.defaultDataSubRatConfig
+ .mapLatest { it.alwaysShowDataRatIcon }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
/** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */
override val defaultMobileIconGroup: StateFlow<MobileIconGroup> =
mobileConnectionsRepo.defaultMobileIconGroup.stateIn(
@@ -188,6 +195,7 @@
MobileIconInteractorImpl(
scope,
activeDataConnectionHasDataEnabled,
+ alwaysShowDataRatIcon,
defaultMobileIconMapping,
defaultMobileIconGroup,
isDefaultConnectionFailed,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index 67ea139..4455801 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -21,6 +21,7 @@
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.ImageView
+import android.widget.Space
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
@@ -29,7 +30,6 @@
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModel
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
@@ -43,6 +43,8 @@
val networkTypeView = view.requireViewById<ImageView>(R.id.mobile_type)
val iconView = view.requireViewById<ImageView>(R.id.mobile_signal)
val mobileDrawable = SignalDrawable(view.context).also { iconView.setImageDrawable(it) }
+ val roamingView = view.requireViewById<ImageView>(R.id.mobile_roaming)
+ val roamingSpace = view.requireViewById<Space>(R.id.mobile_roaming_space)
view.isVisible = true
iconView.isVisible = true
@@ -64,12 +66,21 @@
}
}
+ // Set the roaming indicator
+ launch {
+ viewModel.roaming.distinctUntilChanged().collect { isRoaming ->
+ roamingView.isVisible = isRoaming
+ roamingSpace.isVisible = isRoaming
+ }
+ }
+
// Set the tint
launch {
viewModel.tint.collect { tint ->
val tintList = ColorStateList.valueOf(tint)
iconView.imageTintList = tintList
networkTypeView.imageTintList = tintList
+ roamingView.imageTintList = tintList
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
index 7869021..f4d6111 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
@@ -71,17 +71,23 @@
iconInteractor.isDataConnected,
iconInteractor.isDataEnabled,
iconInteractor.isDefaultConnectionFailed,
- ) { networkTypeIconGroup, dataConnected, dataEnabled, failedConnection ->
- if (!dataConnected || !dataEnabled || failedConnection) {
- null
- } else {
- val desc =
- if (networkTypeIconGroup.dataContentDescription != 0)
- ContentDescription.Resource(networkTypeIconGroup.dataContentDescription)
- else null
- Icon.Resource(networkTypeIconGroup.dataType, desc)
+ iconInteractor.alwaysShowDataRatIcon,
+ ) { networkTypeIconGroup, dataConnected, dataEnabled, failedConnection, alwaysShow ->
+ val desc =
+ if (networkTypeIconGroup.dataContentDescription != 0)
+ ContentDescription.Resource(networkTypeIconGroup.dataContentDescription)
+ else null
+ val icon = Icon.Resource(networkTypeIconGroup.dataType, desc)
+ return@combine when {
+ alwaysShow -> icon
+ !dataConnected -> null
+ !dataEnabled -> null
+ failedConnection -> null
+ else -> icon
}
}
+ val roaming: Flow<Boolean> = iconInteractor.isRoaming
+
val tint: Flow<Int> = flowOf(Color.CYAN)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiActivityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/model/DataActivityModel.kt
similarity index 75%
rename from packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiActivityModel.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/model/DataActivityModel.kt
index a4ca41c..9b41567 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiActivityModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/model/DataActivityModel.kt
@@ -14,20 +14,19 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.pipeline.wifi.shared.model
+package com.android.systemui.statusbar.pipeline.shared.data.model
import com.android.systemui.log.table.Diffable
import com.android.systemui.log.table.TableRowLogger
-/** Provides information on the current wifi activity. */
-data class WifiActivityModel(
- /** True if the wifi has activity in (download). */
+/** Provides information about the current data activity direction */
+data class DataActivityModel(
+ /** True if the connection has activity in (download). */
val hasActivityIn: Boolean,
- /** True if the wifi has activity out (upload). */
+ /** True if the connection has activity out (upload). */
val hasActivityOut: Boolean,
-) : Diffable<WifiActivityModel> {
-
- override fun logDiffs(prevVal: WifiActivityModel, row: TableRowLogger) {
+) : Diffable<DataActivityModel> {
+ override fun logDiffs(prevVal: DataActivityModel, row: TableRowLogger) {
if (prevVal.hasActivityIn != hasActivityIn) {
row.logChange(COL_ACTIVITY_IN, hasActivityIn)
}
@@ -42,6 +41,6 @@
}
}
-const val ACTIVITY_PREFIX = "wifiActivity"
+const val ACTIVITY_PREFIX = "dataActivity"
private const val COL_ACTIVITY_IN = "in"
private const val COL_ACTIVITY_OUT = "out"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
index 0c9c1cc..8144198 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
@@ -42,9 +42,8 @@
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
-import com.android.systemui.statusbar.pipeline.wifi.shared.model.ACTIVITY_PREFIX
-import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiActivityModel
import java.util.concurrent.Executor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -74,7 +73,7 @@
val wifiNetwork: StateFlow<WifiNetworkModel>
/** Observable for the current wifi network activity. */
- val wifiActivity: StateFlow<WifiActivityModel>
+ val wifiActivity: StateFlow<DataActivityModel>
}
/** Real implementation of [WifiRepository]. */
@@ -230,7 +229,7 @@
initialValue = WIFI_NETWORK_DEFAULT
)
- override val wifiActivity: StateFlow<WifiActivityModel> =
+ override val wifiActivity: StateFlow<DataActivityModel> =
if (wifiManager == null) {
Log.w(SB_LOGGING_TAG, "Null WifiManager; skipping activity callback")
flowOf(ACTIVITY_DEFAULT)
@@ -238,7 +237,7 @@
conflatedCallbackFlow {
val callback = TrafficStateCallback { state ->
logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state))
- trySend(trafficStateToWifiActivityModel(state))
+ trySend(trafficStateToDataActivityModel(state))
}
wifiManager.registerTrafficStateCallback(mainExecutor, callback)
awaitClose { wifiManager.unregisterTrafficStateCallback(callback) }
@@ -256,7 +255,9 @@
)
companion object {
- val ACTIVITY_DEFAULT = WifiActivityModel(hasActivityIn = false, hasActivityOut = false)
+ private const val ACTIVITY_PREFIX = "wifiActivity"
+
+ val ACTIVITY_DEFAULT = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
// Start out with no known wifi network.
// Note: [WifiStatusTracker] (the old implementation of connectivity logic) does do an
// initial fetch to get a starting wifi network. But, it uses a deprecated API
@@ -265,8 +266,8 @@
// NetworkCallback inside [wifiNetwork] for our wifi network information.
val WIFI_NETWORK_DEFAULT = WifiNetworkModel.Inactive
- private fun trafficStateToWifiActivityModel(state: Int): WifiActivityModel {
- return WifiActivityModel(
+ private fun trafficStateToDataActivityModel(state: Int): DataActivityModel {
+ return DataActivityModel(
hasActivityIn = state == TrafficStateCallback.DATA_ACTIVITY_IN ||
state == TrafficStateCallback.DATA_ACTIVITY_INOUT,
hasActivityOut = state == TrafficStateCallback.DATA_ACTIVITY_OUT ||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
index ec935fe..93041ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
@@ -19,10 +19,10 @@
import android.net.wifi.WifiManager
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
-import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiActivityModel
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
@@ -50,8 +50,8 @@
/** Our current wifi network. See [WifiNetworkModel]. */
val wifiNetwork: Flow<WifiNetworkModel>
- /** Our current wifi activity. See [WifiActivityModel]. */
- val activity: StateFlow<WifiActivityModel>
+ /** Our current wifi activity. See [DataActivityModel]. */
+ val activity: StateFlow<DataActivityModel>
/** True if we're configured to force-hide the wifi icon and false otherwise. */
val isForceHidden: Flow<Boolean>
@@ -82,7 +82,7 @@
override val wifiNetwork: Flow<WifiNetworkModel> = wifiRepository.wifiNetwork
- override val activity: StateFlow<WifiActivityModel> = wifiRepository.wifiActivity
+ override val activity: StateFlow<DataActivityModel> = wifiRepository.wifiActivity
override val isForceHidden: Flow<Boolean> = connectivityRepository.forceHiddenSlots.map {
it.contains(ConnectivitySlot.WIFI)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
index ec7ba65..07a7595 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
@@ -37,10 +37,10 @@
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
-import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiActivityModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
@@ -147,7 +147,7 @@
)
/** The wifi activity status. Null if we shouldn't display the activity status. */
- private val activity: Flow<WifiActivityModel?> =
+ private val activity: Flow<DataActivityModel?> =
if (!wifiConstants.shouldShowActivityConfig) {
flowOf(null)
} else {
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 dd400b3..d8a8c5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -18,8 +18,8 @@
import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
+import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_STANDARD;
+
import android.app.ActivityManager;
import android.app.Notification;
import android.content.Context;
@@ -57,6 +57,7 @@
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -67,6 +68,11 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.animation.Animator;
+import androidx.core.animation.AnimatorListenerAdapter;
+import androidx.core.animation.AnimatorSet;
+import androidx.core.animation.ObjectAnimator;
+import androidx.core.animation.ValueAnimator;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
@@ -74,6 +80,7 @@
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.animation.InterpolatorsAndroidX;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
@@ -97,6 +104,12 @@
// A marker object that let's us easily find views of this class.
public static final Object VIEW_TAG = new Object();
+ private static final long FOCUS_ANIMATION_TOTAL_DURATION = ANIMATION_DURATION_STANDARD;
+ private static final long FOCUS_ANIMATION_CROSSFADE_DURATION = 50;
+ private static final long FOCUS_ANIMATION_FADE_IN_DELAY = 33;
+ private static final long FOCUS_ANIMATION_FADE_IN_DURATION = 83;
+ private static final float FOCUS_ANIMATION_MIN_SCALE = 0.5f;
+
public final Object mToken = new Object();
private final SendButtonTextWatcher mTextWatcher;
@@ -108,6 +121,7 @@
private RemoteEditText mEditText;
private ImageButton mSendButton;
+ private LinearLayout mContentView;
private GradientDrawable mContentBackground;
private ProgressBar mProgressBar;
private ImageView mDelete;
@@ -115,7 +129,10 @@
private boolean mColorized;
private int mTint;
private boolean mResetting;
- @Nullable private RevealParams mRevealParams;
+ @Nullable
+ private RevealParams mRevealParams;
+ private Rect mContentBackgroundBounds;
+ private boolean mIsFocusAnimationFlagActive;
// TODO(b/193539698): move these to a Controller
private RemoteInputController mController;
@@ -125,6 +142,10 @@
private boolean mSending;
private NotificationViewWrapper mWrapper;
+ private Integer mDefocusTargetHeight = null;
+ private boolean mIsAnimatingAppearance = false;
+
+
// TODO(b/193539698): remove this; views shouldn't have access to their controller, and places
// that need the controller shouldn't have access to the view
private RemoteInputViewController mViewController;
@@ -255,8 +276,8 @@
mDeleteBg.setImageTintBlendMode(BlendMode.SRC_IN);
mDelete.setImageTintBlendMode(BlendMode.SRC_IN);
mDelete.setOnClickListener(v -> setAttachment(null));
- LinearLayout contentView = findViewById(R.id.remote_input_content);
- contentView.setBackground(mContentBackground);
+ mContentView = findViewById(R.id.remote_input_content);
+ mContentView.setBackground(mContentBackground);
mEditText = findViewById(R.id.remote_input_text);
mEditText.setInnerFocusable(false);
// TextView initializes the spell checked when the view is attached to a window.
@@ -398,20 +419,74 @@
return true;
}
- private void onDefocus(boolean animate, boolean logClose) {
+ public boolean isAnimatingAppearance() {
+ return mIsAnimatingAppearance;
+ }
+
+ /**
+ * View will ensure to use at most the provided defocusTargetHeight, when defocusing animated.
+ * This is to ensure that the parent can resize itself to the targetHeight while the defocus
+ * animation of the RemoteInputView is running.
+ *
+ * @param defocusTargetHeight The target height the parent will resize itself to. If null, the
+ * RemoteInputView will not resize itself.
+ */
+ public void setDefocusTargetHeight(Integer defocusTargetHeight) {
+ mDefocusTargetHeight = defocusTargetHeight;
+ }
+
+ @VisibleForTesting
+ void onDefocus(boolean animate, boolean logClose) {
mController.removeRemoteInput(mEntry, mToken);
mEntry.remoteInputText = mEditText.getText();
// During removal, we get reattached and lose focus. Not hiding in that
// case to prevent flicker.
if (!mRemoved) {
- if (animate && mRevealParams != null && mRevealParams.radius > 0) {
- Animator reveal = mRevealParams.createCircularHideAnimator(this);
- reveal.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
- reveal.setDuration(StackStateAnimator.ANIMATION_DURATION_CLOSE_REMOTE_INPUT);
- reveal.addListener(new AnimatorListenerAdapter() {
+ if (animate && mIsFocusAnimationFlagActive) {
+ Animator animator = getDefocusAnimator();
+
+ // When defocusing, the notification needs to shrink. Therefore, we need to free
+ // up the space that is needed for the RemoteInputView. This is done by setting
+ // a negative top margin of the height difference of the RemoteInputView and its
+ // sibling (the actions_container_layout containing the Reply button)
+ if (mDefocusTargetHeight != null && mDefocusTargetHeight < getHeight()
+ && mDefocusTargetHeight >= 0
+ && getLayoutParams() instanceof FrameLayout.LayoutParams) {
+ int heightToShrink = getHeight() - mDefocusTargetHeight;
+ FrameLayout.LayoutParams layoutParams =
+ (FrameLayout.LayoutParams) getLayoutParams();
+ layoutParams.topMargin = -heightToShrink;
+ setLayoutParams(layoutParams);
+ ((ViewGroup) getParent().getParent()).setClipChildren(false);
+ }
+
+ animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
+ //reset top margin after the animation
+ if (getLayoutParams() instanceof FrameLayout.LayoutParams) {
+ FrameLayout.LayoutParams layoutParams =
+ (FrameLayout.LayoutParams) getLayoutParams();
+ layoutParams.topMargin = 0;
+ setLayoutParams(layoutParams);
+ ((ViewGroup) getParent().getParent()).setClipChildren(true);
+ }
+ setVisibility(GONE);
+ if (mWrapper != null) {
+ mWrapper.setRemoteInputVisible(false);
+ }
+ }
+ });
+ animator.start();
+
+ } else if (animate && mRevealParams != null && mRevealParams.radius > 0) {
+ android.animation.Animator reveal = mRevealParams.createCircularHideAnimator(this);
+ reveal.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
+ reveal.setDuration(StackStateAnimator.ANIMATION_DURATION_CLOSE_REMOTE_INPUT);
+ reveal.addListener(new android.animation.AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(android.animation.Animator animation) {
setVisibility(GONE);
if (mWrapper != null) {
mWrapper.setRemoteInputVisible(false);
@@ -533,12 +608,37 @@
mEditText.setText(editTextContent);
}
- public void focusAnimated() {
- if (getVisibility() != VISIBLE && mRevealParams != null) {
- Animator animator = mRevealParams.createCircularRevealAnimator(this);
+ /**
+ * Sets whether the feature flag for the updated inline reply animation is active or not.
+ * @param active
+ */
+ public void setIsFocusAnimationFlagActive(boolean active) {
+ mIsFocusAnimationFlagActive = active;
+ }
+
+ /**
+ * Focuses the RemoteInputView and animates its appearance
+ *
+ * @param crossFadeView view that will be crossfaded during the appearance animation
+ */
+ public void focusAnimated(View crossFadeView) {
+ if (!mIsFocusAnimationFlagActive && getVisibility() != VISIBLE
+ && mRevealParams != null) {
+ android.animation.Animator animator = mRevealParams.createCircularRevealAnimator(this);
animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
animator.start();
+ } else if (mIsFocusAnimationFlagActive && getVisibility() != VISIBLE) {
+ mIsAnimatingAppearance = true;
+ setAlpha(0f);
+ Animator focusAnimator = getFocusAnimator(crossFadeView);
+ focusAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation, boolean isReverse) {
+ mIsAnimatingAppearance = false;
+ }
+ });
+ focusAnimator.start();
}
focus();
}
@@ -737,6 +837,81 @@
mOnSendListeners.remove(listener);
}
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ if (mIsFocusAnimationFlagActive) setPivotY(getMeasuredHeight());
+ if (mContentBackgroundBounds != null) {
+ mContentBackground.setBounds(mContentBackgroundBounds);
+ }
+ }
+
+ private Animator getFocusAnimator(View crossFadeView) {
+ final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 0f, 1f);
+ alphaAnimator.setStartDelay(FOCUS_ANIMATION_FADE_IN_DELAY);
+ alphaAnimator.setDuration(FOCUS_ANIMATION_FADE_IN_DURATION);
+ alphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
+
+ ValueAnimator scaleAnimator = ValueAnimator.ofFloat(FOCUS_ANIMATION_MIN_SCALE, 1f);
+ scaleAnimator.addUpdateListener(valueAnimator -> {
+ setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue());
+ });
+ scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
+ scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
+
+ final Animator crossFadeViewAlphaAnimator =
+ ObjectAnimator.ofFloat(crossFadeView, View.ALPHA, 1f, 0f);
+ crossFadeViewAlphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
+ crossFadeViewAlphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
+ alphaAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation, boolean isReverse) {
+ crossFadeView.setAlpha(1f);
+ }
+ });
+
+ final AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.playTogether(alphaAnimator, scaleAnimator, crossFadeViewAlphaAnimator);
+ return animatorSet;
+ }
+
+ private Animator getDefocusAnimator() {
+ final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 1f, 0f);
+ alphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
+ alphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
+
+ ValueAnimator scaleAnimator = ValueAnimator.ofFloat(1f, FOCUS_ANIMATION_MIN_SCALE);
+ scaleAnimator.addUpdateListener(valueAnimator -> {
+ setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue());
+ });
+ scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
+ scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
+ scaleAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation, boolean isReverse) {
+ setFocusAnimationScaleY(1f);
+ }
+ });
+
+ final AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.playTogether(alphaAnimator, scaleAnimator);
+ return animatorSet;
+ }
+
+ /**
+ * Sets affected view properties for a vertical scale animation
+ *
+ * @param scaleY desired vertical view scale
+ */
+ private void setFocusAnimationScaleY(float scaleY) {
+ int verticalBoundOffset = (int) ((1f - scaleY) * 0.5f * mContentView.getHeight());
+ mContentBackgroundBounds = new Rect(0, verticalBoundOffset, mContentView.getWidth(),
+ mContentView.getHeight() - verticalBoundOffset);
+ mContentBackground.setBounds(mContentBackgroundBounds);
+ mContentView.setBackground(mContentBackground);
+ setTranslationY(verticalBoundOffset);
+ }
+
/** Handler for button click on send action in IME. */
private class EditorActionHandler implements TextView.OnEditorActionListener {
@@ -991,11 +1166,11 @@
this.radius = radius;
}
- Animator createCircularHideAnimator(View view) {
+ android.animation.Animator createCircularHideAnimator(View view) {
return ViewAnimationUtils.createCircularReveal(view, centerX, centerY, radius, 0);
}
- Animator createCircularRevealAnimator(View view) {
+ android.animation.Animator createCircularRevealAnimator(View view) {
return ViewAnimationUtils.createCircularReveal(view, centerX, centerY, 0, radius);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
index f845101..22b4c9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
@@ -30,6 +30,8 @@
import android.view.View
import com.android.internal.logging.UiEventLogger
import com.android.systemui.R
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags.NOTIFICATION_INLINE_REPLY_ANIMATION
import com.android.systemui.statusbar.NotificationRemoteInputManager
import com.android.systemui.statusbar.RemoteInputController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -61,6 +63,8 @@
var revealParams: RevealParams?
+ val isFocusAnimationFlagActive: Boolean
+
/**
* Sets the smart reply that should be inserted in the remote input, or `null` if the user is
* not editing a smart reply.
@@ -117,7 +121,8 @@
private val remoteInputQuickSettingsDisabler: RemoteInputQuickSettingsDisabler,
private val remoteInputController: RemoteInputController,
private val shortcutManager: ShortcutManager,
- private val uiEventLogger: UiEventLogger
+ private val uiEventLogger: UiEventLogger,
+ private val mFlags: FeatureFlags
) : RemoteInputViewController {
private val onSendListeners = ArraySet<OnSendRemoteInputListener>()
@@ -149,6 +154,9 @@
override val isActive: Boolean get() = view.isActive
+ override val isFocusAnimationFlagActive: Boolean
+ get() = mFlags.isEnabled(NOTIFICATION_INLINE_REPLY_ANIMATION)
+
override fun bind() {
if (isBound) return
isBound = true
@@ -159,6 +167,7 @@
view.setSupportedMimeTypes(it.allowedDataTypes)
}
view.setRevealParameters(revealParams)
+ view.setIsFocusAnimationFlagActive(isFocusAnimationFlagActive)
view.addOnEditTextFocusChangedListener(onFocusChangeListener)
view.addOnSendRemoteInputListener(onSendRemoteInputListener)
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/OWNERS b/packages/SystemUI/src/com/android/systemui/stylus/OWNERS
new file mode 100644
index 0000000..7ccb316
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stylus/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 1254381
+azappone@google.com
+achalke@google.com
+juliacr@google.com
+madym@google.com
+mgalhardo@google.com
+petrcermak@google.com
+vanjan@google.com
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt
new file mode 100644
index 0000000..154c6e2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.stylus
+
+import android.content.Context
+import android.hardware.BatteryState
+import android.hardware.input.InputManager
+import android.os.Handler
+import android.util.Log
+import android.view.InputDevice
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * A listener that detects when a stylus has first been used, by detecting 1) the presence of an
+ * internal SOURCE_STYLUS with a battery, or 2) any added SOURCE_STYLUS device with a bluetooth
+ * address.
+ */
+@SysUISingleton
+class StylusFirstUsageListener
+@Inject
+constructor(
+ private val context: Context,
+ private val inputManager: InputManager,
+ private val stylusManager: StylusManager,
+ private val featureFlags: FeatureFlags,
+ @Background private val executor: Executor,
+ @Background private val handler: Handler,
+) : CoreStartable, StylusManager.StylusCallback, InputManager.InputDeviceBatteryListener {
+
+ // Set must be only accessed from the background handler, which is the same handler that
+ // runs the StylusManager callbacks.
+ private val internalStylusDeviceIds: MutableSet<Int> = mutableSetOf()
+ @VisibleForTesting var hasStarted = false
+
+ override fun start() {
+ if (true) return // TODO(b/261826950): remove on main
+ if (hasStarted) return
+ if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return
+ if (inputManager.isStylusEverUsed(context)) return
+ if (!hostDeviceSupportsStylusInput()) return
+
+ hasStarted = true
+ inputManager.inputDeviceIds.forEach(this::onStylusAdded)
+ stylusManager.registerCallback(this)
+ stylusManager.startListener()
+ }
+
+ override fun onStylusAdded(deviceId: Int) {
+ if (!hasStarted) return
+
+ val device = inputManager.getInputDevice(deviceId) ?: return
+ if (device.isExternal || !device.supportsSource(InputDevice.SOURCE_STYLUS)) return
+
+ try {
+ inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
+ internalStylusDeviceIds += deviceId
+ } catch (e: SecurityException) {
+ Log.e(TAG, "$e: Failed to register battery listener for $deviceId ${device.name}.")
+ }
+ }
+
+ override fun onStylusRemoved(deviceId: Int) {
+ if (!hasStarted) return
+
+ if (!internalStylusDeviceIds.contains(deviceId)) return
+ try {
+ inputManager.removeInputDeviceBatteryListener(deviceId, this)
+ internalStylusDeviceIds.remove(deviceId)
+ } catch (e: SecurityException) {
+ Log.e(TAG, "$e: Failed to remove registered battery listener for $deviceId.")
+ }
+ }
+
+ override fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {
+ if (!hasStarted) return
+
+ onRemoteDeviceFound()
+ }
+
+ override fun onBatteryStateChanged(
+ deviceId: Int,
+ eventTimeMillis: Long,
+ batteryState: BatteryState
+ ) {
+ if (!hasStarted) return
+
+ if (batteryState.isPresent) {
+ onRemoteDeviceFound()
+ }
+ }
+
+ private fun onRemoteDeviceFound() {
+ inputManager.setStylusEverUsed(context, true)
+ cleanupListeners()
+ }
+
+ private fun cleanupListeners() {
+ stylusManager.unregisterCallback(this)
+ handler.post {
+ internalStylusDeviceIds.forEach {
+ inputManager.removeInputDeviceBatteryListener(it, this)
+ }
+ }
+ }
+
+ private fun hostDeviceSupportsStylusInput(): Boolean {
+ return inputManager.inputDeviceIds
+ .asSequence()
+ .mapNotNull { inputManager.getInputDevice(it) }
+ .any { it.supportsSource(InputDevice.SOURCE_STYLUS) && !it.isExternal }
+ }
+
+ companion object {
+ private val TAG = StylusFirstUsageListener::class.simpleName.orEmpty()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
new file mode 100644
index 0000000..11233dd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.stylus
+
+import android.hardware.BatteryState
+import android.hardware.input.InputManager
+import android.util.Log
+import android.view.InputDevice
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * A [CoreStartable] that listens to USI stylus battery events, to manage the [StylusUsiPowerUI]
+ * notification controller.
+ */
+@SysUISingleton
+class StylusUsiPowerStartable
+@Inject
+constructor(
+ private val stylusManager: StylusManager,
+ private val inputManager: InputManager,
+ private val stylusUsiPowerUi: StylusUsiPowerUI,
+ private val featureFlags: FeatureFlags,
+ @Background private val executor: Executor,
+) : CoreStartable, StylusManager.StylusCallback, InputManager.InputDeviceBatteryListener {
+
+ override fun onStylusAdded(deviceId: Int) {
+ val device = inputManager.getInputDevice(deviceId) ?: return
+
+ if (!device.isExternal) {
+ registerBatteryListener(deviceId)
+ }
+ }
+
+ override fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {
+ stylusUsiPowerUi.refresh()
+ }
+
+ override fun onStylusBluetoothDisconnected(deviceId: Int, btAddress: String) {
+ stylusUsiPowerUi.refresh()
+ }
+
+ override fun onStylusRemoved(deviceId: Int) {
+ val device = inputManager.getInputDevice(deviceId) ?: return
+
+ if (!device.isExternal) {
+ unregisterBatteryListener(deviceId)
+ }
+ }
+
+ override fun onBatteryStateChanged(
+ deviceId: Int,
+ eventTimeMillis: Long,
+ batteryState: BatteryState
+ ) {
+ if (batteryState.isPresent) {
+ stylusUsiPowerUi.updateBatteryState(batteryState)
+ }
+ }
+
+ private fun registerBatteryListener(deviceId: Int) {
+ try {
+ inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
+ } catch (e: SecurityException) {
+ Log.e(TAG, "$e: Failed to register battery listener for $deviceId.")
+ }
+ }
+
+ private fun unregisterBatteryListener(deviceId: Int) {
+ try {
+ inputManager.removeInputDeviceBatteryListener(deviceId, this)
+ } catch (e: SecurityException) {
+ Log.e(TAG, "$e: Failed to unregister battery listener for $deviceId.")
+ }
+ }
+
+ override fun start() {
+ if (!featureFlags.isEnabled(Flags.ENABLE_USI_BATTERY_NOTIFICATIONS)) return
+ addBatteryListenerForInternalStyluses()
+
+ stylusManager.registerCallback(this)
+ stylusManager.startListener()
+ }
+
+ private fun addBatteryListenerForInternalStyluses() {
+ // For most devices, an active stylus is represented by an internal InputDevice.
+ // This InputDevice will be present in InputManager before CoreStartables run,
+ // and will not be removed. In many cases, it reports the battery level of the stylus.
+ inputManager.inputDeviceIds
+ .asSequence()
+ .mapNotNull { inputManager.getInputDevice(it) }
+ .filter { it.supportsSource(InputDevice.SOURCE_STYLUS) }
+ .forEach { onStylusAdded(it.id) }
+ }
+
+ companion object {
+ private val TAG = StylusUsiPowerStartable::class.simpleName.orEmpty()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
new file mode 100644
index 0000000..70a5b36
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.stylus
+
+import android.Manifest
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.hardware.BatteryState
+import android.hardware.input.InputManager
+import android.os.Handler
+import android.os.UserHandle
+import android.view.InputDevice
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.util.NotificationChannels
+import java.text.NumberFormat
+import javax.inject.Inject
+
+/**
+ * UI controller for the notification that shows when a USI stylus battery is low. The
+ * [StylusUsiPowerStartable], which listens to battery events, uses this controller.
+ */
+@SysUISingleton
+class StylusUsiPowerUI
+@Inject
+constructor(
+ private val context: Context,
+ private val notificationManager: NotificationManagerCompat,
+ private val inputManager: InputManager,
+ @Background private val handler: Handler,
+) {
+
+ // These values must only be accessed on the handler.
+ private var batteryCapacity = 1.0f
+ private var suppressed = false
+
+ fun init() {
+ val filter =
+ IntentFilter().also {
+ it.addAction(ACTION_DISMISSED_LOW_BATTERY)
+ it.addAction(ACTION_CLICKED_LOW_BATTERY)
+ }
+
+ context.registerReceiverAsUser(
+ receiver,
+ UserHandle.ALL,
+ filter,
+ Manifest.permission.DEVICE_POWER,
+ handler,
+ Context.RECEIVER_NOT_EXPORTED,
+ )
+ }
+
+ fun refresh() {
+ handler.post refreshNotification@{
+ if (!suppressed && !hasConnectedBluetoothStylus() && isBatteryBelowThreshold()) {
+ showOrUpdateNotification()
+ return@refreshNotification
+ }
+
+ if (!isBatteryBelowThreshold()) {
+ // Reset suppression when stylus battery is recharged, so that the next time
+ // it reaches a low battery, the notification will show again.
+ suppressed = false
+ }
+ hideNotification()
+ }
+ }
+
+ fun updateBatteryState(batteryState: BatteryState) {
+ handler.post updateBattery@{
+ if (batteryState.capacity == batteryCapacity) return@updateBattery
+
+ batteryCapacity = batteryState.capacity
+ refresh()
+ }
+ }
+
+ /**
+ * Suppression happens when the notification is dismissed by the user. This is to prevent
+ * further battery events with capacities below the threshold from reopening the suppressed
+ * notification.
+ *
+ * Suppression can only be removed when the battery has been recharged - thus restarting the
+ * notification cycle (i.e. next low battery event, notification should show).
+ */
+ fun updateSuppression(suppress: Boolean) {
+ handler.post updateSuppressed@{
+ if (suppressed == suppress) return@updateSuppressed
+
+ suppressed = suppress
+ refresh()
+ }
+ }
+
+ private fun hideNotification() {
+ notificationManager.cancel(USI_NOTIFICATION_ID)
+ }
+
+ private fun showOrUpdateNotification() {
+ val notification =
+ NotificationCompat.Builder(context, NotificationChannels.BATTERY)
+ .setSmallIcon(R.drawable.ic_power_low)
+ .setDeleteIntent(getPendingBroadcast(ACTION_DISMISSED_LOW_BATTERY))
+ .setContentIntent(getPendingBroadcast(ACTION_CLICKED_LOW_BATTERY))
+ .setContentTitle(context.getString(R.string.stylus_battery_low))
+ .setContentText(
+ context.getString(
+ R.string.battery_low_percent_format,
+ NumberFormat.getPercentInstance().format(batteryCapacity)
+ )
+ )
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+ .setLocalOnly(true)
+ .setAutoCancel(true)
+ .build()
+
+ notificationManager.notify(USI_NOTIFICATION_ID, notification)
+ }
+
+ private fun isBatteryBelowThreshold(): Boolean {
+ return batteryCapacity <= LOW_BATTERY_THRESHOLD
+ }
+
+ private fun hasConnectedBluetoothStylus(): Boolean {
+ // TODO(b/257936830): get bt address once input api available
+ return inputManager.inputDeviceIds.any { deviceId ->
+ inputManager.getInputDevice(deviceId).supportsSource(InputDevice.SOURCE_STYLUS)
+ }
+ }
+
+ private fun getPendingBroadcast(action: String): PendingIntent? {
+ return PendingIntent.getBroadcastAsUser(
+ context,
+ 0,
+ Intent(action),
+ PendingIntent.FLAG_IMMUTABLE,
+ UserHandle.CURRENT
+ )
+ }
+
+ private val receiver: BroadcastReceiver =
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ when (intent.action) {
+ ACTION_DISMISSED_LOW_BATTERY -> updateSuppression(true)
+ ACTION_CLICKED_LOW_BATTERY -> {
+ updateSuppression(true)
+ // TODO(b/261584943): open USI device details page
+ }
+ }
+ }
+ }
+
+ companion object {
+ // Low battery threshold matches CrOS, see:
+ // https://source.chromium.org/chromium/chromium/src/+/main:ash/system/power/peripheral_battery_notifier.cc;l=41
+ private const val LOW_BATTERY_THRESHOLD = 0.16f
+
+ private val USI_NOTIFICATION_ID = R.string.stylus_battery_low
+
+ private const val ACTION_DISMISSED_LOW_BATTERY = "StylusUsiPowerUI.dismiss"
+ private const val ACTION_CLICKED_LOW_BATTERY = "StylusUsiPowerUI.click"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
index ea40208..532fbaa 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
@@ -30,11 +30,16 @@
import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS
import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS
import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_TEXT
+import androidx.annotation.CallSuper
import com.android.systemui.CoreStartable
+import com.android.systemui.Dumpable
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.wakelock.WakeLock
+import java.io.PrintWriter
/**
* A generic controller that can temporarily display a new view in a new window.
@@ -44,18 +49,36 @@
*
* The generic type T is expected to contain all the information necessary for the subclasses to
* display the view in a certain state, since they receive <T> in [updateView].
+ *
+ * Some information about display ordering:
+ *
+ * [ViewPriority] defines different priorities for the incoming views. The incoming view will be
+ * displayed so long as its priority is equal to or greater than the currently displayed view.
+ * (Concretely, this means that a [ViewPriority.NORMAL] won't be displayed if a
+ * [ViewPriority.CRITICAL] is currently displayed. But otherwise, the incoming view will get
+ * displayed and kick out the old view).
+ *
+ * Once the currently displayed view times out, we *may* display a previously requested view if it
+ * still has enough time left before its own timeout. The same priority ordering applies.
+ *
+ * Note: [TemporaryViewInfo.id] is the identifier that we use to determine if a call to
+ * [displayView] will just update the current view with new information, or display a completely new
+ * view. This means that you *cannot* change the [TemporaryViewInfo.priority] or
+ * [TemporaryViewInfo.windowTitle] while using the same ID.
*/
-abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : TemporaryViewLogger>(
+abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : TemporaryViewLogger<T>>(
internal val context: Context,
internal val logger: U,
internal val windowManager: WindowManager,
@Main private val mainExecutor: DelayableExecutor,
private val accessibilityManager: AccessibilityManager,
private val configurationController: ConfigurationController,
+ private val dumpManager: DumpManager,
private val powerManager: PowerManager,
@LayoutRes private val viewLayoutRes: Int,
private val wakeLockBuilder: WakeLock.Builder,
-) : CoreStartable {
+ private val systemClock: SystemClock,
+) : CoreStartable, Dumpable {
/**
* Window layout params that will be used as a starting point for the [windowLayoutParams] of
* all subclasses.
@@ -78,27 +101,23 @@
*/
internal abstract val windowLayoutParams: WindowManager.LayoutParams
- /** A container for all the display-related objects. Null if the view is not being displayed. */
- private var displayInfo: DisplayInfo? = null
-
- /** A [Runnable] that, when run, will cancel the pending timeout of the view. */
- private var cancelViewTimeout: Runnable? = null
-
/**
- * A wakelock that is acquired when view is displayed and screen off,
- * then released when view is removed.
+ * A list of the currently active views, ordered from highest priority in the beginning to
+ * lowest priority at the end.
+ *
+ * Whenever the current view disappears, the next-priority view will be displayed if it's still
+ * valid.
*/
- private var wakeLock: WakeLock? = null
+ internal val activeViews: MutableList<DisplayInfo> = mutableListOf()
- /** A string that keeps track of wakelock reason once it is acquired till it gets released */
- private var wakeReasonAcquired: String? = null
+ private fun getCurrentDisplayInfo(): DisplayInfo? {
+ return activeViews.getOrNull(0)
+ }
- /**
- * A stack of pairs of device id and temporary view info. This is used when there may be
- * multiple devices in range, and we want to always display the chip for the most recently
- * active device.
- */
- internal val activeViews: ArrayDeque<Pair<String, T>> = ArrayDeque()
+ @CallSuper
+ override fun start() {
+ dumpManager.registerNormalDumpable(this)
+ }
/**
* Displays the view with the provided [newInfo].
@@ -107,94 +126,139 @@
* display the correct information in the view.
* @param onViewTimeout a runnable that runs after the view timeout.
*/
+ @Synchronized
fun displayView(newInfo: T, onViewTimeout: Runnable? = null) {
- val currentDisplayInfo = displayInfo
-
- // Update our list of active devices by removing it if necessary, then adding back at the
- // front of the list
- val id = newInfo.id
- val position = findAndRemoveFromActiveViewsList(id)
- activeViews.addFirst(Pair(id, newInfo))
-
- if (currentDisplayInfo != null &&
- currentDisplayInfo.info.windowTitle == newInfo.windowTitle) {
- // We're already displaying information in the correctly-titled window, so we just need
- // to update the view.
- currentDisplayInfo.info = newInfo
- updateView(currentDisplayInfo.info, currentDisplayInfo.view)
- } else {
- if (currentDisplayInfo != null) {
- // We're already displaying information but that information is under a different
- // window title. So, we need to remove the old window with the old title and add a
- // new window with the new title.
- removeView(
- id,
- removalReason = "New info has new window title: ${newInfo.windowTitle}"
- )
- }
-
- // At this point, we're guaranteed to no longer be displaying a view.
- // So, set up all our callbacks and inflate the view.
- configurationController.addCallback(displayScaleListener)
-
- wakeLock = if (!powerManager.isScreenOn) {
- // If the screen is off, fully wake it so the user can see the view.
- wakeLockBuilder
- .setTag(newInfo.windowTitle)
- .setLevelsAndFlags(
- PowerManager.FULL_WAKE_LOCK or
- PowerManager.ACQUIRE_CAUSES_WAKEUP
- )
- .build()
- } else {
- // Per b/239426653, we want the view to show over the dream state.
- // If the screen is on, using screen bright level will leave screen on the dream
- // state but ensure the screen will not go off before wake lock is released.
- wakeLockBuilder
- .setTag(newInfo.windowTitle)
- .setLevelsAndFlags(PowerManager.SCREEN_BRIGHT_WAKE_LOCK)
- .build()
- }
- wakeLock?.acquire(newInfo.wakeReason)
- wakeReasonAcquired = newInfo.wakeReason
- logger.logViewAddition(id, newInfo.windowTitle)
- inflateAndUpdateView(newInfo)
- }
-
- // Cancel and re-set the view timeout each time we get a new state.
val timeout = accessibilityManager.getRecommendedTimeoutMillis(
newInfo.timeoutMs,
// Not all views have controls so FLAG_CONTENT_CONTROLS might be superfluous, but
// include it just to be safe.
FLAG_CONTENT_ICONS or FLAG_CONTENT_TEXT or FLAG_CONTENT_CONTROLS
- )
+ )
+ val timeExpirationMillis = systemClock.currentTimeMillis() + timeout
- // Only cancel timeout of the most recent view displayed, as it will be reset.
- if (position == 0) {
- cancelViewTimeout?.run()
+ val currentDisplayInfo = getCurrentDisplayInfo()
+
+ // We're current displaying a chipbar with the same ID, we just need to update its info
+ if (currentDisplayInfo != null && currentDisplayInfo.info.id == newInfo.id) {
+ val view = checkNotNull(currentDisplayInfo.view) {
+ "First item in activeViews list must have a valid view"
+ }
+ logger.logViewUpdate(newInfo)
+ currentDisplayInfo.info = newInfo
+ currentDisplayInfo.timeExpirationMillis = timeExpirationMillis
+ updateTimeout(currentDisplayInfo, timeout, onViewTimeout)
+ updateView(newInfo, view)
+ return
}
- cancelViewTimeout = mainExecutor.executeDelayed(
+
+ val newDisplayInfo = DisplayInfo(
+ info = newInfo,
+ onViewTimeout = onViewTimeout,
+ timeExpirationMillis = timeExpirationMillis,
+ // Null values will be updated to non-null if/when this view actually gets displayed
+ view = null,
+ wakeLock = null,
+ cancelViewTimeout = null,
+ )
+
+ // We're not displaying anything, so just render this new info
+ if (currentDisplayInfo == null) {
+ addCallbacks()
+ activeViews.add(newDisplayInfo)
+ showNewView(newDisplayInfo, timeout)
+ return
+ }
+
+ // The currently displayed info takes higher priority than the new one.
+ // So, just store the new one in case the current one disappears.
+ if (currentDisplayInfo.info.priority > newInfo.priority) {
+ logger.logViewAdditionDelayed(newInfo)
+ // Remove any old information for this id (if it exists) and re-add it to the list in
+ // the right priority spot
+ removeFromActivesIfNeeded(newInfo.id)
+ var insertIndex = 0
+ while (insertIndex < activeViews.size &&
+ activeViews[insertIndex].info.priority > newInfo.priority) {
+ insertIndex++
+ }
+ activeViews.add(insertIndex, newDisplayInfo)
+ return
+ }
+
+ // Else: The newInfo should be displayed and the currentInfo should be hidden
+ hideView(currentDisplayInfo)
+ // Remove any old information for this id (if it exists) and put this info at the beginning
+ removeFromActivesIfNeeded(newDisplayInfo.info.id)
+ activeViews.add(0, newDisplayInfo)
+ showNewView(newDisplayInfo, timeout)
+ }
+
+ private fun showNewView(newDisplayInfo: DisplayInfo, timeout: Int) {
+ logger.logViewAddition(newDisplayInfo.info)
+ createAndAcquireWakeLock(newDisplayInfo)
+ updateTimeout(newDisplayInfo, timeout, newDisplayInfo.onViewTimeout)
+ inflateAndUpdateView(newDisplayInfo)
+ }
+
+ private fun createAndAcquireWakeLock(displayInfo: DisplayInfo) {
+ // TODO(b/262009503): Migrate off of isScrenOn, since it's deprecated.
+ val newWakeLock = if (!powerManager.isScreenOn) {
+ // If the screen is off, fully wake it so the user can see the view.
+ wakeLockBuilder
+ .setTag(displayInfo.info.windowTitle)
+ .setLevelsAndFlags(
+ PowerManager.FULL_WAKE_LOCK or
+ PowerManager.ACQUIRE_CAUSES_WAKEUP
+ )
+ .build()
+ } else {
+ // Per b/239426653, we want the view to show over the dream state.
+ // If the screen is on, using screen bright level will leave screen on the dream
+ // state but ensure the screen will not go off before wake lock is released.
+ wakeLockBuilder
+ .setTag(displayInfo.info.windowTitle)
+ .setLevelsAndFlags(PowerManager.SCREEN_BRIGHT_WAKE_LOCK)
+ .build()
+ }
+ displayInfo.wakeLock = newWakeLock
+ newWakeLock.acquire(displayInfo.info.wakeReason)
+ }
+
+ /**
+ * Creates a runnable that will remove [displayInfo] in [timeout] ms from now.
+ *
+ * @param onViewTimeout an optional runnable that will be run if the view times out.
+ * @return a runnable that, when run, will *cancel* the view's timeout.
+ */
+ private fun updateTimeout(displayInfo: DisplayInfo, timeout: Int, onViewTimeout: Runnable?) {
+ val cancelViewTimeout = mainExecutor.executeDelayed(
{
- removeView(id, REMOVAL_REASON_TIMEOUT)
+ removeView(displayInfo.info.id, REMOVAL_REASON_TIMEOUT)
onViewTimeout?.run()
},
timeout.toLong()
)
+
+ displayInfo.onViewTimeout = onViewTimeout
+ // Cancel old view timeout and re-set it.
+ displayInfo.cancelViewTimeout?.run()
+ displayInfo.cancelViewTimeout = cancelViewTimeout
}
- /** Inflates a new view, updates it with [newInfo], and adds the view to the window. */
- private fun inflateAndUpdateView(newInfo: T) {
+ /** Inflates a new view, updates it with [DisplayInfo.info], and adds the view to the window. */
+ private fun inflateAndUpdateView(displayInfo: DisplayInfo) {
+ val newInfo = displayInfo.info
val newView = LayoutInflater
.from(context)
.inflate(viewLayoutRes, null) as ViewGroup
- val newViewController = TouchableRegionViewController(newView, this::getTouchableRegion)
- newViewController.init()
+ displayInfo.view = newView
// We don't need to hold on to the view controller since we never set anything additional
// on it -- it will be automatically cleaned up when the view is detached.
- val newDisplayInfo = DisplayInfo(newView, newInfo)
- displayInfo = newDisplayInfo
- updateView(newDisplayInfo.info, newDisplayInfo.view)
+ val newViewController = TouchableRegionViewController(newView, this::getTouchableRegion)
+ newViewController.init()
+
+ updateView(newInfo, newView)
val paramsWithTitle = WindowManager.LayoutParams().also {
it.copyFrom(windowLayoutParams)
@@ -206,11 +270,15 @@
}
/** Removes then re-inflates the view. */
+ @Synchronized
private fun reinflateView() {
- val currentViewInfo = displayInfo ?: return
+ val currentDisplayInfo = getCurrentDisplayInfo() ?: return
- windowManager.removeView(currentViewInfo.view)
- inflateAndUpdateView(currentViewInfo.info)
+ val view = checkNotNull(currentDisplayInfo.view) {
+ "First item in activeViews list must have a valid view"
+ }
+ windowManager.removeView(view)
+ inflateAndUpdateView(currentDisplayInfo)
}
private val displayScaleListener = object : ConfigurationController.ConfigurationListener {
@@ -219,68 +287,122 @@
}
}
+ private fun addCallbacks() {
+ configurationController.addCallback(displayScaleListener)
+ }
+
+ private fun removeCallbacks() {
+ configurationController.removeCallback(displayScaleListener)
+ }
+
/**
- * Hides the view given its [id].
+ * Completely removes the view for the given [id], both visually and from our internal store.
*
* @param id the id of the device responsible of displaying the temp view.
* @param removalReason a short string describing why the view was removed (timeout, state
* change, etc.)
*/
+ @Synchronized
fun removeView(id: String, removalReason: String) {
- val currentDisplayInfo = displayInfo ?: return
-
- val removalPosition = findAndRemoveFromActiveViewsList(id)
- if (removalPosition == null) {
- logger.logViewRemovalIgnored(id, "view not found in the list")
- return
- }
- if (removalPosition != 0) {
- logger.logViewRemovalIgnored(id, "most recent view is being displayed.")
- return
- }
logger.logViewRemoval(id, removalReason)
- val newViewToDisplay = if (activeViews.isEmpty()) {
- null
- } else {
- activeViews[0].second
+ val displayInfo = activeViews.firstOrNull { it.info.id == id }
+ if (displayInfo == null) {
+ logger.logViewRemovalIgnored(id, "View not found in list")
+ return
}
- val currentView = currentDisplayInfo.view
- animateViewOut(currentView) {
- windowManager.removeView(currentView)
- wakeLock?.release(wakeReasonAcquired)
- }
+ val currentlyDisplayedView = activeViews[0]
+ // Remove immediately (instead as part of the animation end runnable) so that if a new view
+ // event comes in while this view is animating out, we still display the new view
+ // appropriately.
+ activeViews.remove(displayInfo)
- configurationController.removeCallback(displayScaleListener)
- // Re-set to null immediately (instead as part of the animation end runnable) so
- // that if a new view event comes in while this view is animating out, we still display
- // the new view appropriately.
- displayInfo = null
// No need to time the view out since it's already gone
- cancelViewTimeout?.run()
+ displayInfo.cancelViewTimeout?.run()
+
+ if (displayInfo.view == null) {
+ logger.logViewRemovalIgnored(id, "No view to remove")
+ return
+ }
+
+ if (currentlyDisplayedView.info.id != id) {
+ logger.logViewRemovalIgnored(id, "View isn't the currently displayed view")
+ return
+ }
+
+ removeViewFromWindow(displayInfo)
+
+ // Prune anything that's already timed out before determining if we should re-display a
+ // different chipbar.
+ removeTimedOutViews()
+ val newViewToDisplay = getCurrentDisplayInfo()
if (newViewToDisplay != null) {
- mainExecutor.executeDelayed({ displayView(newViewToDisplay)}, DISPLAY_VIEW_DELAY)
+ val timeout = newViewToDisplay.timeExpirationMillis - systemClock.currentTimeMillis()
+ // TODO(b/258019006): We may want to have a delay before showing the new view so
+ // that the UI translation looks a bit smoother. But, we expect this to happen
+ // rarely so it may not be worth the extra complexity.
+ showNewView(newViewToDisplay, timeout.toInt())
+ } else {
+ removeCallbacks()
}
}
/**
- * Finds and removes the active view with the given [id] from the stack, or null if there is no
- * active view with that ID
- *
- * @param id that temporary view belonged to.
- *
- * @return index of the view in the stack , otherwise null.
+ * Hides the view from the window, but keeps [displayInfo] around in [activeViews] in case it
+ * should be re-displayed later.
*/
- private fun findAndRemoveFromActiveViewsList(id: String): Int? {
- for (i in 0 until activeViews.size) {
- if (activeViews[i].first == id) {
- activeViews.removeAt(i)
- return i
- }
+ private fun hideView(displayInfo: DisplayInfo) {
+ logger.logViewHidden(displayInfo.info)
+ removeViewFromWindow(displayInfo)
+ }
+
+ private fun removeViewFromWindow(displayInfo: DisplayInfo) {
+ val view = displayInfo.view
+ if (view == null) {
+ logger.logViewRemovalIgnored(displayInfo.info.id, "View is null")
+ return
}
- return null
+ displayInfo.view = null // Need other places??
+ animateViewOut(view) {
+ windowManager.removeView(view)
+ displayInfo.wakeLock?.release(displayInfo.info.wakeReason)
+ }
+ }
+
+ @Synchronized
+ private fun removeTimedOutViews() {
+ val invalidViews = activeViews
+ .filter { it.timeExpirationMillis <
+ systemClock.currentTimeMillis() + MIN_REQUIRED_TIME_FOR_REDISPLAY }
+
+ invalidViews.forEach {
+ activeViews.remove(it)
+ logger.logViewExpiration(it.info)
+ }
+ }
+
+ @Synchronized
+ private fun removeFromActivesIfNeeded(id: String) {
+ val toRemove = activeViews.find { it.info.id == id }
+ toRemove?.let {
+ it.cancelViewTimeout?.run()
+ activeViews.remove(it)
+ }
+ }
+
+ @Synchronized
+ @CallSuper
+ override fun dump(pw: PrintWriter, args: Array<out String>) {
+ pw.println("Current time millis: ${systemClock.currentTimeMillis()}")
+ pw.println("Active views size: ${activeViews.size}")
+ activeViews.forEachIndexed { index, displayInfo ->
+ pw.println("View[$index]:")
+ pw.println(" info=${displayInfo.info}")
+ pw.println(" hasView=${displayInfo.view != null}")
+ pw.println(" timeExpiration=${displayInfo.timeExpirationMillis}")
+ }
}
/**
@@ -311,17 +433,45 @@
}
/** A container for all the display-related state objects. */
- private inner class DisplayInfo(
- /** The view currently being displayed. */
- val view: ViewGroup,
+ inner class DisplayInfo(
+ /**
+ * The view currently being displayed.
+ *
+ * Null if this info isn't currently being displayed.
+ */
+ var view: ViewGroup?,
- /** The info currently being displayed. */
+ /** The info that should be displayed if/when this is the highest priority view. */
var info: T,
+
+ /**
+ * The system time at which this display info should expire and never be displayed again.
+ */
+ var timeExpirationMillis: Long,
+
+ /**
+ * The wake lock currently held by this view. Must be released when the view disappears.
+ *
+ * Null if this info isn't currently being displayed.
+ */
+ var wakeLock: WakeLock?,
+
+ /**
+ * See [displayView].
+ */
+ var onViewTimeout: Runnable?,
+
+ /**
+ * A runnable that, when run, will cancel this view's timeout.
+ *
+ * Null if this info isn't currently being displayed.
+ */
+ var cancelViewTimeout: Runnable?,
)
}
private const val REMOVAL_REASON_TIMEOUT = "TIMEOUT"
-const val DISPLAY_VIEW_DELAY = 50L
+private const val MIN_REQUIRED_TIME_FOR_REDISPLAY = 1000
private data class IconInfo(
val iconName: String,
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
index df83960..5596cf6 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
@@ -42,6 +42,20 @@
* The id of the temporary view.
*/
abstract val id: String
+
+ /** The priority for this view. */
+ abstract val priority: ViewPriority
}
const val DEFAULT_TIMEOUT_MILLIS = 10000
+
+/**
+ * The priority of the view being displayed.
+ *
+ * Must be ordered from lowest priority to highest priority. (CRITICAL is currently the highest
+ * priority.)
+ */
+enum class ViewPriority {
+ NORMAL,
+ CRITICAL,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewLogger.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewLogger.kt
index 133a384..ec6965a 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewLogger.kt
@@ -20,20 +20,79 @@
import com.android.systemui.plugins.log.LogLevel
/** A logger for temporary view changes -- see [TemporaryViewDisplayController]. */
-open class TemporaryViewLogger(
+open class TemporaryViewLogger<T : TemporaryViewInfo>(
internal val buffer: LogBuffer,
internal val tag: String,
) {
- /** Logs that we added the view with the given [id] in a window titled [windowTitle]. */
- fun logViewAddition(id: String, windowTitle: String) {
+ fun logViewExpiration(info: T) {
buffer.log(
tag,
LogLevel.DEBUG,
{
- str1 = windowTitle
- str2 = id
+ str1 = info.id
+ str2 = info.windowTitle
+ str3 = info.priority.name
},
- { "View added. window=$str1 id=$str2" }
+ { "View timeout has already expired; removing. id=$str1 window=$str2 priority=$str3" }
+ )
+ }
+
+ fun logViewUpdate(info: T) {
+ buffer.log(
+ tag,
+ LogLevel.DEBUG,
+ {
+ str1 = info.id
+ str2 = info.windowTitle
+ str3 = info.priority.name
+ },
+ { "Existing view updated with new data. id=$str1 window=$str2 priority=$str3" }
+ )
+ }
+
+ fun logViewAdditionDelayed(info: T) {
+ buffer.log(
+ tag,
+ LogLevel.DEBUG,
+ {
+ str1 = info.id
+ str2 = info.windowTitle
+ str3 = info.priority.name
+ },
+ {
+ "New view can't be displayed because higher priority view is currently " +
+ "displayed. New view id=$str1 window=$str2 priority=$str3"
+ }
+ )
+ }
+
+ /** Logs that we added the view with the given information. */
+ fun logViewAddition(info: T) {
+ buffer.log(
+ tag,
+ LogLevel.DEBUG,
+ {
+ str1 = info.id
+ str2 = info.windowTitle
+ str3 = info.priority.name
+ },
+ { "View added. id=$str1 window=$str2 priority=$str3" }
+ )
+ }
+
+ fun logViewHidden(info: T) {
+ buffer.log(
+ tag,
+ LogLevel.DEBUG,
+ {
+ str1 = info.id
+ str2 = info.windowTitle
+ str3 = info.priority.name
+ },
+ {
+ "View hidden in favor of newer view. " +
+ "Hidden view id=$str1 window=$str2 priority=$str3"
+ }
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
index 4d91e35..fd2c705 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
@@ -22,10 +22,13 @@
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
+import android.view.View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
+import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE
import android.view.ViewGroup
import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import android.widget.TextView
+import androidx.annotation.IdRes
import com.android.internal.widget.CachingIconView
import com.android.systemui.Gefingerpoken
import com.android.systemui.R
@@ -38,11 +41,13 @@
import com.android.systemui.common.ui.binder.TintedIconViewBinder
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.view.ViewUtil
import com.android.systemui.util.wakelock.WakeLock
import javax.inject.Inject
@@ -71,12 +76,14 @@
@Main mainExecutor: DelayableExecutor,
accessibilityManager: AccessibilityManager,
configurationController: ConfigurationController,
+ dumpManager: DumpManager,
powerManager: PowerManager,
private val falsingManager: FalsingManager,
private val falsingCollector: FalsingCollector,
private val viewUtil: ViewUtil,
private val vibratorHelper: VibratorHelper,
wakeLockBuilder: WakeLock.Builder,
+ systemClock: SystemClock,
) : TemporaryViewDisplayController<ChipbarInfo, ChipbarLogger>(
context,
logger,
@@ -84,9 +91,11 @@
mainExecutor,
accessibilityManager,
configurationController,
+ dumpManager,
powerManager,
R.layout.chipbar,
wakeLockBuilder,
+ systemClock,
) {
private lateinit var parent: ChipbarRootView
@@ -110,6 +119,8 @@
}
)
+ currentView.setTag(INFO_TAG, newInfo)
+
// Detect falsing touches on the chip.
parent = currentView.requireViewById(R.id.chipbar_root_view)
parent.touchHandler = object : Gefingerpoken {
@@ -162,8 +173,11 @@
} else {
""
}
- currentView.requireViewById<ViewGroup>(R.id.chipbar_inner).contentDescription =
- "$loadedIconDesc${newInfo.text.loadText(context)}"
+
+ val chipInnerView = currentView.getInnerView()
+ chipInnerView.contentDescription = "$loadedIconDesc${newInfo.text.loadText(context)}"
+ chipInnerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE
+ maybeGetAccessibilityFocus(newInfo, currentView)
// ---- Haptics ----
newInfo.vibrationEffect?.let {
@@ -171,23 +185,37 @@
}
}
+ private fun maybeGetAccessibilityFocus(info: ChipbarInfo?, view: ViewGroup) {
+ // Don't steal focus unless the chipbar has something interactable.
+ // (The chipbar is marked as a live region, so its content will be announced whenever the
+ // content changes.)
+ if (info?.endItem is ChipbarEndItem.Button) {
+ view.getInnerView().requestAccessibilityFocus()
+ } else {
+ view.getInnerView().clearAccessibilityFocus()
+ }
+ }
+
override fun animateViewIn(view: ViewGroup) {
- val chipInnerView = view.requireViewById<ViewGroup>(R.id.chipbar_inner)
ViewHierarchyAnimator.animateAddition(
- chipInnerView,
+ view.getInnerView(),
ViewHierarchyAnimator.Hotspot.TOP,
Interpolators.EMPHASIZED_DECELERATE,
duration = ANIMATION_IN_DURATION,
includeMargins = true,
includeFadeIn = true,
// We can only request focus once the animation finishes.
- onAnimationEnd = { chipInnerView.requestAccessibilityFocus() },
+ onAnimationEnd = {
+ maybeGetAccessibilityFocus(view.getTag(INFO_TAG) as ChipbarInfo?, view)
+ },
)
}
override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) {
+ val innerView = view.getInnerView()
+ innerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_NONE
ViewHierarchyAnimator.animateRemoval(
- view.requireViewById<ViewGroup>(R.id.chipbar_inner),
+ innerView,
ViewHierarchyAnimator.Hotspot.TOP,
Interpolators.EMPHASIZED_ACCELERATE,
ANIMATION_OUT_DURATION,
@@ -196,7 +224,9 @@
)
}
- override fun start() {}
+ private fun ViewGroup.getInnerView(): ViewGroup {
+ return requireViewById(R.id.chipbar_inner)
+ }
override fun getTouchableRegion(view: View, outRect: Rect) {
viewUtil.setRectToViewWindowLocation(view, outRect)
@@ -213,3 +243,4 @@
private const val ANIMATION_IN_DURATION = 500L
private const val ANIMATION_OUT_DURATION = 250L
+@IdRes private val INFO_TAG = R.id.tag_chipbar_info
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
index a3eef80..dd4bd26 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
@@ -22,6 +22,7 @@
import com.android.systemui.common.shared.model.Text
import com.android.systemui.common.shared.model.TintedIcon
import com.android.systemui.temporarydisplay.TemporaryViewInfo
+import com.android.systemui.temporarydisplay.ViewPriority
/**
* A container for all the state needed to display a chipbar via [ChipbarCoordinator].
@@ -42,6 +43,7 @@
override val wakeReason: String,
override val timeoutMs: Int,
override val id: String,
+ override val priority: ViewPriority,
) : TemporaryViewInfo() {
companion object {
@AttrRes const val DEFAULT_ICON_TINT_ATTR = android.R.attr.textColorPrimary
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarLogger.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarLogger.kt
index e477cd6..fcfbe0a 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarLogger.kt
@@ -29,7 +29,7 @@
@Inject
constructor(
@ChipbarLog buffer: LogBuffer,
-) : TemporaryViewLogger(buffer, "ChipbarLog") {
+) : TemporaryViewLogger<ChipbarInfo>(buffer, "ChipbarLog") {
/**
* Logs that the chipbar was updated to display in a window named [windowTitle], with [text] and
* [endItemDesc].
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
index 6216acd..101bd44 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
@@ -16,6 +16,7 @@
package com.android.systemui.unfold
+import android.annotation.BinderThread
import android.content.Context
import android.hardware.devicestate.DeviceStateManager
import android.os.PowerManager
@@ -41,7 +42,6 @@
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
/**
@@ -52,7 +52,7 @@
class FoldAodAnimationController
@Inject
constructor(
- @Main private val executor: DelayableExecutor,
+ @Main private val mainExecutor: DelayableExecutor,
private val context: Context,
private val deviceStateManager: DeviceStateManager,
private val wakefulnessLifecycle: WakefulnessLifecycle,
@@ -89,7 +89,7 @@
override fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) {
this.centralSurfaces = centralSurfaces
- deviceStateManager.registerCallback(executor, FoldListener())
+ deviceStateManager.registerCallback(mainExecutor, FoldListener())
wakefulnessLifecycle.addObserver(this)
// TODO(b/254878364): remove this call to NPVC.getView()
@@ -139,7 +139,8 @@
* @param onReady callback when the animation is ready
* @see [com.android.systemui.keyguard.KeyguardViewMediator]
*/
- fun onScreenTurningOn(onReady: Runnable) {
+ @BinderThread
+ fun onScreenTurningOn(onReady: Runnable) = mainExecutor.execute {
if (shouldPlayAnimation) {
// The device was not dozing and going to sleep after folding, play the animation
@@ -179,12 +180,13 @@
}
}
- fun onScreenTurnedOn() {
+ @BinderThread
+ fun onScreenTurnedOn() = mainExecutor.execute {
if (shouldPlayAnimation) {
cancelAnimation?.run()
// Post starting the animation to the next frame to avoid junk due to inset changes
- cancelAnimation = executor.executeDelayed(startAnimationRunnable, /* delayMillis= */ 0)
+ cancelAnimation = mainExecutor.executeDelayed(startAnimationRunnable, /* delayMillis= */ 0)
shouldPlayAnimation = false
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt
index 79b42b8..9269df3 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt
@@ -16,12 +16,18 @@
package com.android.systemui.unfold
+import android.content.ContentResolver
import android.content.Context
import android.hardware.devicestate.DeviceStateManager
+import android.util.Log
import com.android.internal.util.LatencyTracker
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.keyguard.ScreenLifecycle
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider.Companion.areAnimationsEnabled
+import com.android.systemui.util.Compile
+import java.util.Optional
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -41,17 +47,19 @@
constructor(
private val latencyTracker: LatencyTracker,
private val deviceStateManager: DeviceStateManager,
+ private val transitionProgressProvider: Optional<UnfoldTransitionProgressProvider>,
@UiBackground private val uiBgExecutor: Executor,
private val context: Context,
+ private val contentResolver: ContentResolver,
private val screenLifecycle: ScreenLifecycle
-) : ScreenLifecycle.Observer {
+) : ScreenLifecycle.Observer, TransitionProgressListener {
private var folded: Boolean? = null
+ private var isTransitionEnabled: Boolean? = null
private val foldStateListener = FoldStateListener(context)
private val isFoldable: Boolean
get() =
- context
- .resources
+ context.resources
.getIntArray(com.android.internal.R.array.config_foldedDeviceStates)
.isNotEmpty()
@@ -62,6 +70,11 @@
}
deviceStateManager.registerCallback(uiBgExecutor, foldStateListener)
screenLifecycle.addObserver(this)
+ if (transitionProgressProvider.isPresent) {
+ // Might not be present if the device is not a foldable device or unfold transition
+ // is disabled in the device configuration
+ transitionProgressProvider.get().addCallback(this)
+ }
}
/**
@@ -71,16 +84,72 @@
* end action event only if we previously received a fold state.
*/
override fun onScreenTurnedOn() {
- if (folded == false) {
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "onScreenTurnedOn: folded = $folded, isTransitionEnabled = $isTransitionEnabled"
+ )
+ }
+
+ // We use onScreenTurnedOn event to finish tracking only if we are not playing
+ // the unfold animation (e.g. it could be disabled because of battery saver).
+ // When animation is enabled finishing of the tracking will be done in onTransitionStarted.
+ if (folded == false && isTransitionEnabled == false) {
latencyTracker.onActionEnd(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD)
+
+ if (DEBUG) {
+ Log.d(TAG, "onScreenTurnedOn: ending ACTION_SWITCH_DISPLAY_UNFOLD")
+ }
+ }
+ }
+
+ /**
+ * This callback is used to end the metric when the unfold animation is enabled because it could
+ * add an additional delay to synchronize with launcher.
+ */
+ override fun onTransitionStarted() {
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "onTransitionStarted: folded = $folded, isTransitionEnabled = $isTransitionEnabled"
+ )
+ }
+
+ if (folded == false && isTransitionEnabled == true) {
+ latencyTracker.onActionEnd(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD)
+
+ if (DEBUG) {
+ Log.d(TAG, "onTransitionStarted: ending ACTION_SWITCH_DISPLAY_UNFOLD")
+ }
}
}
private fun onFoldEvent(folded: Boolean) {
- if (this.folded != folded) {
+ val oldFolded = this.folded
+
+ if (oldFolded != folded) {
this.folded = folded
- if (!folded) { // unfolding started
+
+ if (DEBUG) {
+ Log.d(TAG, "Received onFoldEvent = $folded")
+ }
+
+ // Do not start tracking when oldFolded is null, this means that this is the first
+ // onFoldEvent after booting the device or starting SystemUI and not actual folding or
+ // unfolding the device.
+ if (oldFolded != null && !folded) {
+ // Unfolding started
latencyTracker.onActionStart(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD)
+ isTransitionEnabled =
+ transitionProgressProvider.isPresent && contentResolver.areAnimationsEnabled()
+
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "Starting ACTION_SWITCH_DISPLAY_UNFOLD, " +
+ "isTransitionEnabled = $isTransitionEnabled"
+ )
+ }
}
}
}
@@ -88,3 +157,6 @@
private inner class FoldStateListener(context: Context) :
DeviceStateManager.FoldStateListener(context, { onFoldEvent(it) })
}
+
+private const val TAG = "UnfoldLatencyTracker"
+private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE)
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
index b2ec27c..9cca950 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.unfold
+import android.annotation.BinderThread
import android.content.ContentResolver
import android.content.Context
import android.graphics.PixelFormat
@@ -34,9 +35,7 @@
import android.view.SurfaceSession
import android.view.WindowManager
import android.view.WindowlessWindowManager
-import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.statusbar.LightRevealEffect
import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.LinearLightRevealEffect
@@ -45,7 +44,7 @@
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.unfold.updates.RotationChangeProvider
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider.Companion.areAnimationsEnabled
-import com.android.systemui.util.Assert.isMainThread
+import com.android.systemui.util.concurrency.ThreadFactory
import com.android.systemui.util.traceSection
import com.android.wm.shell.displayareahelper.DisplayAreaHelper
import java.util.Optional
@@ -64,14 +63,16 @@
private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
private val displayAreaHelper: Optional<DisplayAreaHelper>,
@Main private val executor: Executor,
- @UiBackground private val backgroundExecutor: Executor,
- @Background private val bgHandler: Handler,
+ private val threadFactory: ThreadFactory,
private val rotationChangeProvider: RotationChangeProvider,
) {
private val transitionListener = TransitionListener()
private val rotationWatcher = RotationWatcher()
+ private lateinit var bgHandler: Handler
+ private lateinit var bgExecutor: Executor
+
private lateinit var wwm: WindowlessWindowManager
private lateinit var unfoldedDisplayInfo: DisplayInfo
private lateinit var overlayContainer: SurfaceControl
@@ -84,7 +85,12 @@
private var currentRotation: Int = context.display!!.rotation
fun init() {
- deviceStateManager.registerCallback(executor, FoldListener())
+ // This method will be called only on devices where this animation is enabled,
+ // so normally this thread won't be created
+ bgHandler = threadFactory.buildHandlerOnNewThread(TAG)
+ bgExecutor = threadFactory.buildDelayableExecutorOnHandler(bgHandler)
+
+ deviceStateManager.registerCallback(bgExecutor, FoldListener())
unfoldTransitionProgressProvider.addCallback(transitionListener)
rotationChangeProvider.addCallback(rotationWatcher)
@@ -122,20 +128,23 @@
* @param onOverlayReady callback when the overlay is drawn and visible on the screen
* @see [com.android.systemui.keyguard.KeyguardViewMediator]
*/
+ @BinderThread
fun onScreenTurningOn(onOverlayReady: Runnable) {
- Trace.beginSection("UnfoldLightRevealOverlayAnimation#onScreenTurningOn")
- try {
- // Add the view only if we are unfolding and this is the first screen on
- if (!isFolded && !isUnfoldHandled && contentResolver.areAnimationsEnabled()) {
- executeInBackground { addOverlay(onOverlayReady, reason = UNFOLD) }
- isUnfoldHandled = true
- } else {
- // No unfold transition, immediately report that overlay is ready
- executeInBackground { ensureOverlayRemoved() }
- onOverlayReady.run()
+ executeInBackground {
+ Trace.beginSection("$TAG#onScreenTurningOn")
+ try {
+ // Add the view only if we are unfolding and this is the first screen on
+ if (!isFolded && !isUnfoldHandled && contentResolver.areAnimationsEnabled()) {
+ addOverlay(onOverlayReady, reason = UNFOLD)
+ isUnfoldHandled = true
+ } else {
+ // No unfold transition, immediately report that overlay is ready
+ ensureOverlayRemoved()
+ onOverlayReady.run()
+ }
+ } finally {
+ Trace.endSection()
}
- } finally {
- Trace.endSection()
}
}
@@ -154,17 +163,18 @@
LightRevealScrim(context, null).apply {
revealEffect = createLightRevealEffect()
isScrimOpaqueChangedListener = Consumer {}
- revealAmount = when (reason) {
- FOLD -> TRANSPARENT
- UNFOLD -> BLACK
- }
+ revealAmount =
+ when (reason) {
+ FOLD -> TRANSPARENT
+ UNFOLD -> BLACK
+ }
}
val params = getLayoutParams()
newRoot.setView(newView, params)
if (onOverlayReady != null) {
- Trace.beginAsyncSection("UnfoldLightRevealOverlayAnimation#relayout", 0)
+ Trace.beginAsyncSection("$TAG#relayout", 0)
newRoot.relayout(params) { transaction ->
val vsyncId = Choreographer.getSfInstance().vsyncId
@@ -179,8 +189,8 @@
transaction
.setFrameTimelineVsync(vsyncId + 1)
- .addTransactionCommittedListener(backgroundExecutor) {
- Trace.endAsyncSection("UnfoldLightRevealOverlayAnimation#relayout", 0)
+ .addTransactionCommittedListener(bgExecutor) {
+ Trace.endAsyncSection("$TAG#relayout", 0)
onOverlayReady.run()
}
.apply()
@@ -233,7 +243,8 @@
}
private fun getUnfoldedDisplayInfo(): DisplayInfo =
- displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)
+ displayManager
+ .getDisplays(DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)
.asSequence()
.map { DisplayInfo().apply { it.getDisplayInfo(this) } }
.filter { it.type == Display.TYPE_INTERNAL }
@@ -261,10 +272,10 @@
private inner class RotationWatcher : RotationChangeProvider.RotationListener {
override fun onRotationChanged(newRotation: Int) {
- traceSection("UnfoldLightRevealOverlayAnimation#onRotationChanged") {
- if (currentRotation != newRotation) {
- currentRotation = newRotation
- executeInBackground {
+ executeInBackground {
+ traceSection("$TAG#onRotationChanged") {
+ if (currentRotation != newRotation) {
+ currentRotation = newRotation
scrimView?.revealEffect = createLightRevealEffect()
root?.relayout(getLayoutParams())
}
@@ -274,7 +285,10 @@
}
private fun executeInBackground(f: () -> Unit) {
- ensureInMainThread()
+ check(Looper.myLooper() != bgHandler.looper) {
+ "Trying to execute using background handler while already running" +
+ " in the background handler"
+ }
// The UiBackground executor is not used as it doesn't have a prepared looper.
bgHandler.post(f)
}
@@ -283,25 +297,25 @@
check(Looper.myLooper() == bgHandler.looper) { "Not being executed in the background!" }
}
- private fun ensureInMainThread() {
- isMainThread()
- }
-
private inner class FoldListener :
FoldStateListener(
context,
Consumer { isFolded ->
if (isFolded) {
- executeInBackground { ensureOverlayRemoved() }
+ ensureOverlayRemoved()
isUnfoldHandled = false
}
this.isFolded = isFolded
}
)
- private enum class AddOverlayReason { FOLD, UNFOLD }
+ private enum class AddOverlayReason {
+ FOLD,
+ UNFOLD
+ }
private companion object {
+ const val TAG = "UnfoldLightRevealOverlayAnimation"
const val ROTATION_ANIMATION_OVERLAY_Z_INDEX = Integer.MAX_VALUE
// Put the unfold overlay below the rotation animation screenshot to hide the moment
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
index 7da2d47..52b7fb6 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
@@ -39,9 +39,9 @@
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.user_switcher_fullscreen)
- window.decorView.getWindowInsetsController().apply {
- setSystemBarsBehavior(BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE)
- hide(Type.systemBars())
+ window.decorView.windowInsetsController?.let { controller ->
+ controller.systemBarsBehavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
+ controller.hide(Type.systemBars())
}
val viewModel =
ViewModelProvider(this, viewModelFactory.get())[UserSwitcherViewModel::class.java]
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/PendingTasksContainer.kt b/packages/SystemUI/src/com/android/systemui/util/concurrency/PendingTasksContainer.kt
index 6cd384f..ceebcb7 100644
--- a/packages/SystemUI/src/com/android/systemui/util/concurrency/PendingTasksContainer.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/PendingTasksContainer.kt
@@ -25,8 +25,11 @@
*/
class PendingTasksContainer {
- private var pendingTasksCount: AtomicInteger = AtomicInteger(0)
- private var completionCallback: AtomicReference<Runnable> = AtomicReference()
+ @Volatile
+ private var pendingTasksCount = AtomicInteger(0)
+
+ @Volatile
+ private var completionCallback = AtomicReference<Runnable>()
/**
* Registers a task that we should wait for
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
deleted file mode 100644
index fa8c8982..0000000
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.keyguard
-
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-class KeyguardListenQueueTest : SysuiTestCase() {
-
- @Test
- fun testQueueIsBounded() {
- val size = 5
- val queue = KeyguardListenQueue(sizePerModality = size)
-
- val fingerprints = List(100) { fingerprintModel(it) }
- fingerprints.forEach { queue.add(it) }
-
- assertThat(queue.models).containsExactlyElementsIn(fingerprints.takeLast(size))
-
- val faces = List(100) { faceModel(it) }
- faces.forEach { queue.add(it) }
-
- assertThat(queue.models).containsExactlyElementsIn(
- faces.takeLast(size) + fingerprints.takeLast(5)
- )
-
- repeat(100) {
- queue.add(faceModel(-1))
- queue.add(fingerprintModel(-1))
- }
- assertThat(queue.models).hasSize(2 * size)
- assertThat(queue.models.count { it.userId == -1 }).isEqualTo(2 * size)
- }
-}
-
-private fun fingerprintModel(user: Int) = KeyguardFingerprintListenModel(
- timeMillis = System.currentTimeMillis(),
- userId = user,
- listening = false,
- biometricEnabledForUser = false,
- bouncerIsOrWillShow = false,
- canSkipBouncer = false,
- credentialAttempted = false,
- deviceInteractive = false,
- dreaming = false,
- fingerprintDisabled = false,
- fingerprintLockedOut = false,
- goingToSleep = false,
- keyguardGoingAway = false,
- keyguardIsVisible = false,
- keyguardOccluded = false,
- occludingAppRequestingFp = false,
- primaryUser = false,
- shouldListenSfpsState = false,
- shouldListenForFingerprintAssistant = false,
- strongerAuthRequired = false,
- switchingUser = false,
- udfps = false,
- userDoesNotHaveTrust = false
-)
-
-private fun faceModel(user: Int) = KeyguardFaceListenModel(
- timeMillis = System.currentTimeMillis(),
- userId = user,
- listening = false,
- authInterruptActive = false,
- biometricSettingEnabledForUser = false,
- bouncerFullyShown = false,
- faceAndFpNotAuthenticated = false,
- faceAuthAllowed = true,
- faceDisabled = false,
- faceLockedOut = false,
- goingToSleep = false,
- keyguardAwake = false,
- keyguardGoingAway = false,
- listeningForFaceAssistant = false,
- occludingAppRequestingFaceAuth = false,
- primaryUser = false,
- secureCameraLaunched = false,
- supportsDetect = true,
- switchingUser = false,
- udfpsBouncerShowing = false,
- udfpsFingerDown = false,
- userNotTrustedOrDetectionIsNeeded = false
-)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 849ff08..13cd328 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -823,7 +823,7 @@
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
mTestableLooper.processAllMessages();
lockscreenBypassIsAllowed();
- mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
+ mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, true /* newlyUnlocked */,
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */,
new ArrayList<>());
keyguardIsVisible();
@@ -834,7 +834,7 @@
public void testIgnoresAuth_whenTrustAgentOnKeyguard_withoutBypass() {
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
mTestableLooper.processAllMessages();
- mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
+ mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, true /* newlyUnlocked */,
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */, new ArrayList<>());
keyguardIsVisible();
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
@@ -1049,8 +1049,8 @@
@Test
public void testGetUserCanSkipBouncer_whenTrust() {
int user = KeyguardUpdateMonitor.getCurrentUser();
- mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, user, 0 /* flags */,
- new ArrayList<>());
+ mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, true /* newlyUnlocked */,
+ user, 0 /* flags */, new ArrayList<>());
assertThat(mKeyguardUpdateMonitor.getUserCanSkipBouncer(user)).isTrue();
}
@@ -1314,7 +1314,7 @@
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
// WHEN trust is enabled (ie: via smartlock)
- mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
+ mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, true /* newlyUnlocked */,
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */, new ArrayList<>());
// THEN we shouldn't listen for udfps
@@ -1418,13 +1418,14 @@
@Test
public void testShowTrustGrantedMessage_onTrustGranted() {
// WHEN trust is enabled (ie: via some trust agent) with a trustGranted string
- mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
+ mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, true /* newlyUnlocked */,
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */,
Arrays.asList("Unlocked by wearable"));
// THEN the showTrustGrantedMessage should be called with the first message
verify(mTestCallback).onTrustGrantedForCurrentUser(
- anyBoolean(),
+ anyBoolean() /* dismissKeyguard */,
+ eq(true) /* newlyUnlocked */,
eq(new TrustGrantFlags(0)),
eq("Unlocked by wearable"));
}
@@ -1870,6 +1871,7 @@
// WHEN onTrustChanged with TRUST_DISMISS_KEYGUARD flag
mKeyguardUpdateMonitor.onTrustChanged(
true /* enabled */,
+ true /* newlyUnlocked */,
getCurrentUser() /* userId */,
TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD /* flags */,
null /* trustGrantedMessages */);
@@ -1877,6 +1879,7 @@
// THEN onTrustGrantedForCurrentUser callback called
verify(callback).onTrustGrantedForCurrentUser(
eq(true) /* dismissKeyguard */,
+ eq(true) /* newlyUnlocked */,
eq(new TrustGrantFlags(TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD)),
eq(null) /* message */
);
@@ -1893,6 +1896,7 @@
// WHEN onTrustChanged with TRUST_DISMISS_KEYGUARD flag
mKeyguardUpdateMonitor.onTrustChanged(
true /* enabled */,
+ true /* newlyUnlocked */,
getCurrentUser() /* userId */,
TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD /* flags */,
null /* trustGrantedMessages */);
@@ -1900,6 +1904,7 @@
// THEN onTrustGrantedForCurrentUser callback called
verify(callback).onTrustGrantedForCurrentUser(
eq(false) /* dismissKeyguard */,
+ eq(true) /* newlyUnlocked */,
eq(new TrustGrantFlags(TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD)),
eq(null) /* message */
);
@@ -1917,6 +1922,7 @@
// WHEN onTrustChanged for a different user
mKeyguardUpdateMonitor.onTrustChanged(
true /* enabled */,
+ true /* newlyUnlocked */,
546 /* userId, not the current userId */,
0 /* flags */,
null /* trustGrantedMessages */);
@@ -1924,6 +1930,7 @@
// THEN onTrustGrantedForCurrentUser callback called
verify(callback, never()).onTrustGrantedForCurrentUser(
anyBoolean() /* dismissKeyguard */,
+ eq(true) /* newlyUnlocked */,
anyObject() /* flags */,
anyString() /* message */
);
@@ -1941,6 +1948,7 @@
// flags (temporary & rewable is active unlock)
mKeyguardUpdateMonitor.onTrustChanged(
true /* enabled */,
+ true /* newlyUnlocked */,
getCurrentUser() /* userId */,
TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD
| TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE /* flags */,
@@ -1949,6 +1957,7 @@
// THEN onTrustGrantedForCurrentUser callback called
verify(callback).onTrustGrantedForCurrentUser(
eq(true) /* dismissKeyguard */,
+ eq(true) /* newlyUnlocked */,
eq(new TrustGrantFlags(TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD
| TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE)),
eq(null) /* message */
@@ -1968,6 +1977,7 @@
// WHEN onTrustChanged with INITIATED_BY_USER flag
mKeyguardUpdateMonitor.onTrustChanged(
true /* enabled */,
+ true /* newlyUnlocked */,
getCurrentUser() /* userId, not the current userId */,
TrustAgentService.FLAG_GRANT_TRUST_INITIATED_BY_USER /* flags */,
null /* trustGrantedMessages */);
@@ -1975,6 +1985,7 @@
// THEN onTrustGrantedForCurrentUser callback called
verify(callback, never()).onTrustGrantedForCurrentUser(
eq(true) /* dismissKeyguard */,
+ eq(true) /* newlyUnlocked */,
eq(new TrustGrantFlags(TrustAgentService.FLAG_GRANT_TRUST_INITIATED_BY_USER)),
anyString() /* message */
);
@@ -1992,6 +2003,7 @@
// WHEN onTrustChanged with INITIATED_BY_USER flag
mKeyguardUpdateMonitor.onTrustChanged(
true /* enabled */,
+ true /* newlyUnlocked */,
getCurrentUser() /* userId, not the current userId */,
TrustAgentService.FLAG_GRANT_TRUST_INITIATED_BY_USER
| TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE /* flags */,
@@ -2000,6 +2012,7 @@
// THEN onTrustGrantedForCurrentUser callback called
verify(callback, never()).onTrustGrantedForCurrentUser(
eq(true) /* dismissKeyguard */,
+ eq(true) /* newlyUnlocked */,
eq(new TrustGrantFlags(TrustAgentService.FLAG_GRANT_TRUST_INITIATED_BY_USER
| TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE)),
anyString() /* message */
@@ -2310,6 +2323,7 @@
private void currentUserDoesNotHaveTrust() {
mKeyguardUpdateMonitor.onTrustChanged(
false,
+ false,
KeyguardUpdateMonitor.getCurrentUser(),
-1,
new ArrayList<>()
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
index 5734c3d..34e78eb 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
@@ -52,8 +52,6 @@
private lateinit var foldAodAnimationController: FoldAodAnimationController
@Mock
private lateinit var unfoldAnimation: UnfoldLightRevealOverlayAnimation
- @Mock
- private lateinit var screenLifecycle: ScreenLifecycle
@Captor
private lateinit var readyCaptor: ArgumentCaptor<Runnable>
@@ -69,13 +67,8 @@
.thenReturn(foldAodAnimationController)
screenOnCoordinator = ScreenOnCoordinator(
- screenLifecycle,
Optional.of(unfoldComponent),
- FakeExecution()
)
-
- // Make sure screen events are registered to observe
- verify(screenLifecycle).addObserver(screenOnCoordinator)
}
@Test
@@ -93,9 +86,7 @@
fun testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() {
// Recreate with empty unfoldComponent
screenOnCoordinator = ScreenOnCoordinator(
- screenLifecycle,
Optional.empty(),
- FakeExecution()
)
screenOnCoordinator.onScreenTurningOn(runnable)
@@ -105,11 +96,11 @@
private fun onUnfoldOverlayReady() {
verify(unfoldAnimation).onScreenTurningOn(capture(readyCaptor))
- readyCaptor.getValue().run()
+ readyCaptor.value.run()
}
private fun onFoldAodReady() {
verify(foldAodAnimationController).onScreenTurningOn(capture(readyCaptor))
- readyCaptor.getValue().run()
+ readyCaptor.value.run()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
index d6e621f..b4e85c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
@@ -16,12 +16,14 @@
package com.android.systemui.clipboardoverlay;
+import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_SHOWN;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_DISMISS_TAPPED;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SHARE_TAPPED;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SWIPE_DISMISSED;
import static com.android.systemui.flags.Flags.CLIPBOARD_REMOTE_BEHAVIOR;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -29,10 +31,13 @@
import static org.mockito.Mockito.when;
import android.animation.Animator;
+import android.app.RemoteAction;
import android.content.ClipData;
import android.content.ClipDescription;
+import android.content.Context;
import android.net.Uri;
import android.os.PersistableBundle;
+import android.view.textclassifier.TextLinks;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -42,6 +47,8 @@
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.screenshot.TimeoutHandler;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.After;
import org.junit.Before;
@@ -50,7 +57,12 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.Optional;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -80,6 +92,8 @@
private ArgumentCaptor<ClipboardOverlayView.ClipboardOverlayCallbacks> mOverlayCallbacksCaptor;
private ClipboardOverlayView.ClipboardOverlayCallbacks mCallbacks;
+ private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
@@ -101,6 +115,7 @@
mTimeoutHandler,
mFeatureFlags,
mClipboardUtils,
+ mExecutor,
mUiEventLogger);
verify(mClipboardOverlayView).setCallbacks(mOverlayCallbacksCaptor.capture());
mCallbacks = mOverlayCallbacksCaptor.getValue();
@@ -237,4 +252,29 @@
verify(mUiEventLogger).log(CLIPBOARD_OVERLAY_DISMISS_TAPPED, 0, "second.package");
verifyNoMoreInteractions(mUiEventLogger);
}
+
+ @Test
+ public void test_logOnClipboardActionsShown() {
+ ClipData.Item item = mSampleClipData.getItemAt(0);
+ item.setTextLinks(Mockito.mock(TextLinks.class));
+ mFeatureFlags.set(CLIPBOARD_REMOTE_BEHAVIOR, true);
+ when(mClipboardUtils.isRemoteCopy(any(Context.class), any(ClipData.class), anyString()))
+ .thenReturn(true);
+ when(mClipboardUtils.getAction(any(ClipData.Item.class), anyString()))
+ .thenReturn(Optional.of(Mockito.mock(RemoteAction.class)));
+ when(mClipboardOverlayView.post(any(Runnable.class))).thenAnswer(new Answer<Object>() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ ((Runnable) invocation.getArgument(0)).run();
+ return null;
+ }
+ });
+
+ mOverlayController.setClipData(
+ new ClipData(mSampleClipData.getDescription(), item), "actionShownSource");
+ mExecutor.runAllReady();
+
+ verify(mUiEventLogger).log(CLIPBOARD_OVERLAY_ACTION_SHOWN, 0, "actionShownSource");
+ verifyNoMoreInteractions(mUiEventLogger);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java
index 09b1699..aea6be3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java
@@ -16,13 +16,24 @@
package com.android.systemui.clipboardoverlay;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.when;
+import android.app.RemoteAction;
import android.content.ClipData;
import android.content.ClipDescription;
import android.os.PersistableBundle;
import android.testing.TestableResources;
+import android.util.ArrayMap;
+import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationManager;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextLinks;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -30,19 +41,84 @@
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.google.android.collect.Lists;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Map;
+import java.util.Optional;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ClipboardOverlayUtilsTest extends SysuiTestCase {
private ClipboardOverlayUtils mClipboardUtils;
+ @Mock
+ private TextClassificationManager mTextClassificationManager;
+ @Mock
+ private TextClassifier mTextClassifier;
+
+ @Mock
+ private ClipData.Item mClipDataItem;
@Before
public void setUp() {
- mClipboardUtils = new ClipboardOverlayUtils();
+ MockitoAnnotations.initMocks(this);
+
+ when(mTextClassificationManager.getTextClassifier()).thenReturn(mTextClassifier);
+ mClipboardUtils = new ClipboardOverlayUtils(mTextClassificationManager);
+ }
+
+ @Test
+ public void test_getAction_noLinks_returnsEmptyOptional() {
+ ClipData.Item item = new ClipData.Item("no text links");
+ item.setTextLinks(Mockito.mock(TextLinks.class));
+
+ Optional<RemoteAction> action = mClipboardUtils.getAction(item, "");
+
+ assertTrue(action.isEmpty());
+ }
+
+ @Test
+ public void test_getAction_returnsFirstLink() {
+ when(mClipDataItem.getTextLinks()).thenReturn(getFakeTextLinks());
+ when(mClipDataItem.getText()).thenReturn("");
+ RemoteAction actionA = constructRemoteAction("abc");
+ RemoteAction actionB = constructRemoteAction("def");
+ TextClassification classificationA = Mockito.mock(TextClassification.class);
+ when(classificationA.getActions()).thenReturn(Lists.newArrayList(actionA));
+ TextClassification classificationB = Mockito.mock(TextClassification.class);
+ when(classificationB.getActions()).thenReturn(Lists.newArrayList(actionB));
+ when(mTextClassifier.classifyText(anyString(), anyInt(), anyInt(), isNull())).thenReturn(
+ classificationA, classificationB);
+
+ RemoteAction result = mClipboardUtils.getAction(mClipDataItem, "def").orElse(null);
+
+ assertEquals(actionA, result);
+ }
+
+ @Test
+ public void test_getAction_skipsMatchingComponent() {
+ when(mClipDataItem.getTextLinks()).thenReturn(getFakeTextLinks());
+ when(mClipDataItem.getText()).thenReturn("");
+ RemoteAction actionA = constructRemoteAction("abc");
+ RemoteAction actionB = constructRemoteAction("def");
+ TextClassification classificationA = Mockito.mock(TextClassification.class);
+ when(classificationA.getActions()).thenReturn(Lists.newArrayList(actionA));
+ TextClassification classificationB = Mockito.mock(TextClassification.class);
+ when(classificationB.getActions()).thenReturn(Lists.newArrayList(actionB));
+ when(mTextClassifier.classifyText(anyString(), anyInt(), anyInt(), isNull())).thenReturn(
+ classificationA, classificationB);
+
+ RemoteAction result = mClipboardUtils.getAction(mClipDataItem, "abc").orElse(null);
+
+ assertEquals(actionB, result);
}
@Test
@@ -92,7 +168,7 @@
assertFalse(mClipboardUtils.isRemoteCopy(mContext, data, ""));
}
- static ClipData constructClipData(String[] mimeTypes, ClipData.Item item,
+ private static ClipData constructClipData(String[] mimeTypes, ClipData.Item item,
PersistableBundle extras) {
ClipDescription description = new ClipDescription("Test", mimeTypes);
if (extras != null) {
@@ -100,4 +176,20 @@
}
return new ClipData(description, item);
}
+
+ private static RemoteAction constructRemoteAction(String packageName) {
+ RemoteAction action = Mockito.mock(RemoteAction.class, Answers.RETURNS_DEEP_STUBS);
+ when(action.getActionIntent().getIntent().getComponent().getPackageName())
+ .thenReturn(packageName);
+ return action;
+ }
+
+ private static TextLinks getFakeTextLinks() {
+ TextLinks.Builder textLinks = new TextLinks.Builder("test");
+ final Map<String, Float> scores = new ArrayMap<>();
+ scores.put(TextClassifier.TYPE_EMAIL, 1f);
+ textLinks.addLink(0, 0, scores);
+ textLinks.addLink(0, 0, scores);
+ return textLinks.build();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamCallbackControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamCallbackControllerTest.kt
new file mode 100644
index 0000000..003efbf
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamCallbackControllerTest.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.dreams
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DreamCallbackControllerTest : SysuiTestCase() {
+
+ @Mock private lateinit var callback: DreamCallbackController.DreamCallback
+
+ private lateinit var underTest: DreamCallbackController
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ underTest = DreamCallbackController()
+ }
+
+ @Test
+ fun testOnWakeUpInvokesCallback() {
+ underTest.addCallback(callback)
+ underTest.onWakeUp()
+ verify(callback).onWakeUp()
+
+ // Adding twice should not invoke twice
+ reset(callback)
+ underTest.addCallback(callback)
+ underTest.onWakeUp()
+ verify(callback, times(1)).onWakeUp()
+
+ // After remove, no call to callback
+ reset(callback)
+ underTest.removeCallback(callback)
+ underTest.onWakeUp()
+ verify(callback, never()).onWakeUp()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
index 99406ed..6c23254 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
@@ -1,18 +1,25 @@
package com.android.systemui.dreams
-import android.animation.Animator
import android.animation.AnimatorSet
import android.testing.AndroidTestingRunner
+import android.view.View
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dreams.complication.ComplicationHostViewController
+import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel
import com.android.systemui.statusbar.BlurUtils
-import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.anyLong
+import org.mockito.Mockito.eq
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
@@ -23,19 +30,11 @@
class DreamOverlayAnimationsControllerTest : SysuiTestCase() {
companion object {
+ private const val DREAM_BLUR_RADIUS = 50
private const val DREAM_IN_BLUR_ANIMATION_DURATION = 1L
- private const val DREAM_IN_BLUR_ANIMATION_DELAY = 2L
private const val DREAM_IN_COMPLICATIONS_ANIMATION_DURATION = 3L
- private const val DREAM_IN_TOP_COMPLICATIONS_ANIMATION_DELAY = 4L
- private const val DREAM_IN_BOTTOM_COMPLICATIONS_ANIMATION_DELAY = 5L
- private const val DREAM_OUT_TRANSLATION_Y_DISTANCE = 6
- private const val DREAM_OUT_TRANSLATION_Y_DURATION = 7L
- private const val DREAM_OUT_TRANSLATION_Y_DELAY_BOTTOM = 8L
- private const val DREAM_OUT_TRANSLATION_Y_DELAY_TOP = 9L
- private const val DREAM_OUT_ALPHA_DURATION = 10L
- private const val DREAM_OUT_ALPHA_DELAY_BOTTOM = 11L
- private const val DREAM_OUT_ALPHA_DELAY_TOP = 12L
- private const val DREAM_OUT_BLUR_DURATION = 13L
+ private const val DREAM_IN_TRANSLATION_Y_DISTANCE = 6
+ private const val DREAM_IN_TRANSLATION_Y_DURATION = 7L
}
@Mock private lateinit var mockAnimator: AnimatorSet
@@ -43,6 +42,8 @@
@Mock private lateinit var hostViewController: ComplicationHostViewController
@Mock private lateinit var statusBarViewController: DreamOverlayStatusBarViewController
@Mock private lateinit var stateController: DreamOverlayStateController
+ @Mock private lateinit var configController: ConfigurationController
+ @Mock private lateinit var transitionViewModel: DreamingToLockscreenTransitionViewModel
private lateinit var controller: DreamOverlayAnimationsController
@Before
@@ -54,72 +55,49 @@
hostViewController,
statusBarViewController,
stateController,
+ DREAM_BLUR_RADIUS,
+ transitionViewModel,
+ configController,
DREAM_IN_BLUR_ANIMATION_DURATION,
- DREAM_IN_BLUR_ANIMATION_DELAY,
DREAM_IN_COMPLICATIONS_ANIMATION_DURATION,
- DREAM_IN_TOP_COMPLICATIONS_ANIMATION_DELAY,
- DREAM_IN_BOTTOM_COMPLICATIONS_ANIMATION_DELAY,
- DREAM_OUT_TRANSLATION_Y_DISTANCE,
- DREAM_OUT_TRANSLATION_Y_DURATION,
- DREAM_OUT_TRANSLATION_Y_DELAY_BOTTOM,
- DREAM_OUT_TRANSLATION_Y_DELAY_TOP,
- DREAM_OUT_ALPHA_DURATION,
- DREAM_OUT_ALPHA_DELAY_BOTTOM,
- DREAM_OUT_ALPHA_DELAY_TOP,
- DREAM_OUT_BLUR_DURATION
+ DREAM_IN_TRANSLATION_Y_DISTANCE,
+ DREAM_IN_TRANSLATION_Y_DURATION,
)
+
+ val mockView: View = mock()
+ whenever(mockView.resources).thenReturn(mContext.resources)
+
+ runBlocking(Dispatchers.Main.immediate) { controller.init(mockView) }
}
@Test
- fun testExitAnimationOnEnd() {
- val mockCallback: () -> Unit = mock()
+ fun testWakeUpCallsExecutor() {
+ val mockExecutor: DelayableExecutor = mock()
+ val mockCallback: Runnable = mock()
- controller.startExitAnimations(
- view = mock(),
+ controller.wakeUp(
doneCallback = mockCallback,
- animatorBuilder = { mockAnimator }
+ executor = mockExecutor,
)
- val captor = argumentCaptor<Animator.AnimatorListener>()
- verify(mockAnimator).addListener(captor.capture())
- val listener = captor.value
-
- verify(mockCallback, never()).invoke()
- listener.onAnimationEnd(mockAnimator)
- verify(mockCallback, times(1)).invoke()
+ verify(mockExecutor).executeDelayed(eq(mockCallback), anyLong())
}
@Test
- fun testCancellation() {
- controller.startExitAnimations(
- view = mock(),
- doneCallback = mock(),
- animatorBuilder = { mockAnimator }
- )
-
- verify(mockAnimator, never()).cancel()
- controller.cancelAnimations()
- verify(mockAnimator, times(1)).cancel()
- }
-
- @Test
- fun testExitAfterStartWillCancel() {
+ fun testWakeUpAfterStartWillCancel() {
val mockStartAnimator: AnimatorSet = mock()
- val mockExitAnimator: AnimatorSet = mock()
- controller.startEntryAnimations(view = mock(), animatorBuilder = { mockStartAnimator })
+ controller.startEntryAnimations(animatorBuilder = { mockStartAnimator })
verify(mockStartAnimator, never()).cancel()
- controller.startExitAnimations(
- view = mock(),
+ controller.wakeUp(
doneCallback = mock(),
- animatorBuilder = { mockExitAnimator }
+ executor = mock(),
)
// Verify that we cancelled the start animator in favor of the exit
// animator.
verify(mockStartAnimator, times(1)).cancel()
- verify(mockExitAnimator, never()).cancel()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index 73c226d..2799a25 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -203,7 +203,7 @@
mController.onViewAttached();
- verify(mAnimationsController).startEntryAnimations(mDreamOverlayContainerView);
+ verify(mAnimationsController).startEntryAnimations();
verify(mAnimationsController, never()).cancelAnimations();
}
@@ -213,7 +213,7 @@
mController.onViewAttached();
- verify(mAnimationsController, never()).startEntryAnimations(mDreamOverlayContainerView);
+ verify(mAnimationsController, never()).startEntryAnimations();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
index ffb8342..d6f8dea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
@@ -113,6 +113,9 @@
@Mock
UiEventLogger mUiEventLogger;
+ @Mock
+ DreamCallbackController mDreamCallbackController;
+
@Captor
ArgumentCaptor<View> mViewCaptor;
@@ -141,7 +144,8 @@
mStateController,
mKeyguardUpdateMonitor,
mUiEventLogger,
- LOW_LIGHT_COMPONENT);
+ LOW_LIGHT_COMPONENT,
+ mDreamCallbackController);
}
@Test
@@ -353,6 +357,7 @@
mService.onWakeUp(callback);
mMainExecutor.runAllReady();
verify(mDreamOverlayContainerViewController).wakeUp(callback, mMainExecutor);
+ verify(mDreamCallbackController).onWakeUp();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutParamsTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutParamsTest.java
index fdb4cc4..e414942 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutParamsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutParamsTest.java
@@ -17,6 +17,10 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
@@ -29,6 +33,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.function.Consumer;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -197,4 +202,19 @@
assertThat(paramsWithConstraint.constraintSpecified()).isTrue();
assertThat(paramsWithConstraint.getConstraint()).isEqualTo(constraint);
}
+
+ @Test
+ public void testIteratePositions() {
+ final int positions = ComplicationLayoutParams.POSITION_TOP
+ | ComplicationLayoutParams.POSITION_START
+ | ComplicationLayoutParams.POSITION_END;
+ final Consumer<Integer> consumer = mock(Consumer.class);
+
+ ComplicationLayoutParams.iteratePositions(consumer, positions);
+
+ verify(consumer).accept(ComplicationLayoutParams.POSITION_TOP);
+ verify(consumer).accept(ComplicationLayoutParams.POSITION_START);
+ verify(consumer).accept(ComplicationLayoutParams.POSITION_END);
+ verify(consumer, never()).accept(ComplicationLayoutParams.POSITION_BOTTOM);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
index cef452b..5e4a43f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
@@ -20,11 +20,18 @@
import android.content.ContentValues
import android.content.pm.PackageManager
import android.content.pm.ProviderInfo
+import android.os.Bundle
+import android.os.Handler
+import android.os.IBinder
import android.os.UserHandle
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.SurfaceControlViewHost
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SystemUIAppComponentFactoryBase
import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
@@ -36,6 +43,9 @@
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
+import com.android.systemui.keyguard.ui.preview.KeyguardPreviewRenderer
+import com.android.systemui.keyguard.ui.preview.KeyguardPreviewRendererFactory
+import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
@@ -43,40 +53,54 @@
import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
+import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
@Mock private lateinit var lockPatternUtils: LockPatternUtils
@Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var previewRendererFactory: KeyguardPreviewRendererFactory
+ @Mock private lateinit var previewRenderer: KeyguardPreviewRenderer
+ @Mock private lateinit var backgroundHandler: Handler
+ @Mock private lateinit var previewSurfacePackage: SurfaceControlViewHost.SurfacePackage
+ @Mock private lateinit var launchAnimator: DialogLaunchAnimator
private lateinit var underTest: KeyguardQuickAffordanceProvider
+ private lateinit var testScope: TestScope
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
+ whenever(previewRenderer.surfacePackage).thenReturn(previewSurfacePackage)
+ whenever(previewRendererFactory.create(any())).thenReturn(previewRenderer)
+ whenever(backgroundHandler.looper).thenReturn(TestableLooper.get(this).looper)
underTest = KeyguardQuickAffordanceProvider()
- val scope = CoroutineScope(IMMEDIATE)
+ val testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
val localUserSelectionManager =
KeyguardQuickAffordanceLocalUserSelectionManager(
context = context,
@@ -96,7 +120,7 @@
)
val remoteUserSelectionManager =
KeyguardQuickAffordanceRemoteUserSelectionManager(
- scope = scope,
+ scope = testScope.backgroundScope,
userTracker = userTracker,
clientFactory = FakeKeyguardQuickAffordanceProviderClientFactory(userTracker),
userHandle = UserHandle.SYSTEM,
@@ -104,7 +128,7 @@
val quickAffordanceRepository =
KeyguardQuickAffordanceRepository(
appContext = context,
- scope = scope,
+ scope = testScope.backgroundScope,
localUserSelectionManager = localUserSelectionManager,
remoteUserSelectionManager = remoteUserSelectionManager,
userTracker = userTracker,
@@ -123,8 +147,8 @@
),
legacySettingSyncer =
KeyguardQuickAffordanceLegacySettingSyncer(
- scope = scope,
- backgroundDispatcher = IMMEDIATE,
+ scope = testScope.backgroundScope,
+ backgroundDispatcher = testDispatcher,
secureSettings = FakeSettings(),
selectionsManager = localUserSelectionManager,
),
@@ -145,8 +169,17 @@
featureFlags =
FakeFeatureFlags().apply {
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
+ set(Flags.LOCKSCREEN_CUSTOM_CLOCKS, true)
+ set(Flags.REVAMPED_WALLPAPER_UI, true)
},
repository = { quickAffordanceRepository },
+ launchAnimator = launchAnimator,
+ )
+ underTest.previewManager =
+ KeyguardRemotePreviewManager(
+ previewRendererFactory = previewRendererFactory,
+ mainDispatcher = testDispatcher,
+ backgroundHandler = backgroundHandler,
)
underTest.attachInfoForTesting(
@@ -190,7 +223,7 @@
@Test
fun `insert and query selection`() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
val slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
val affordanceId = AFFORDANCE_2
val affordanceName = AFFORDANCE_2_NAME
@@ -214,7 +247,7 @@
@Test
fun `query slots`() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
assertThat(querySlots())
.isEqualTo(
listOf(
@@ -232,7 +265,7 @@
@Test
fun `query affordances`() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
assertThat(queryAffordances())
.isEqualTo(
listOf(
@@ -252,7 +285,7 @@
@Test
fun `delete and query selection`() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
insertSelection(
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
affordanceId = AFFORDANCE_1,
@@ -286,7 +319,7 @@
@Test
fun `delete all selections in a slot`() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
insertSelection(
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
affordanceId = AFFORDANCE_1,
@@ -316,6 +349,23 @@
)
}
+ @Test
+ fun preview() =
+ testScope.runTest {
+ val hostToken: IBinder = mock()
+ whenever(previewRenderer.hostToken).thenReturn(hostToken)
+ val extras = Bundle()
+
+ val result = underTest.call("whatever", "anything", extras)
+
+ verify(previewRenderer).render()
+ verify(hostToken).linkToDeath(any(), anyInt())
+ assertThat(result!!).isNotNull()
+ assertThat(result.get(KeyguardRemotePreviewManager.KEY_PREVIEW_SURFACE_PACKAGE))
+ .isEqualTo(previewSurfacePackage)
+ assertThat(result.containsKey(KeyguardRemotePreviewManager.KEY_PREVIEW_CALLBACK))
+ }
+
private fun insertSelection(
slotId: String,
affordanceId: String,
@@ -451,7 +501,6 @@
)
companion object {
- private val IMMEDIATE = Dispatchers.Main.immediate
private const val AFFORDANCE_1 = "affordance_1"
private const val AFFORDANCE_2 = "affordance_2"
private const val AFFORDANCE_1_NAME = "affordance_1_name"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java
index f46d58d..70a0415 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java
@@ -58,15 +58,15 @@
@Test
public void screenTurningOn() throws Exception {
Runnable onDrawn = () -> {};
- mScreen.dispatchScreenTurningOn(onDrawn);
+ mScreen.dispatchScreenTurningOn();
assertEquals(ScreenLifecycle.SCREEN_TURNING_ON, mScreen.getScreenState());
- verify(mScreenObserverMock).onScreenTurningOn(onDrawn);
+ verify(mScreenObserverMock).onScreenTurningOn();
}
@Test
public void screenTurnedOn() throws Exception {
- mScreen.dispatchScreenTurningOn(null);
+ mScreen.dispatchScreenTurningOn();
mScreen.dispatchScreenTurnedOn();
assertEquals(ScreenLifecycle.SCREEN_ON, mScreen.getScreenState());
@@ -75,7 +75,7 @@
@Test
public void screenTurningOff() throws Exception {
- mScreen.dispatchScreenTurningOn(null);
+ mScreen.dispatchScreenTurningOn();
mScreen.dispatchScreenTurnedOn();
mScreen.dispatchScreenTurningOff();
@@ -85,7 +85,7 @@
@Test
public void screenTurnedOff() throws Exception {
- mScreen.dispatchScreenTurningOn(null);
+ mScreen.dispatchScreenTurningOn();
mScreen.dispatchScreenTurnedOn();
mScreen.dispatchScreenTurningOff();
mScreen.dispatchScreenTurnedOff();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
new file mode 100644
index 0000000..7c10108
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.android.systemui.keyguard.data.quickaffordance
+
+import android.net.Uri
+import android.provider.Settings
+import android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+import android.provider.Settings.Global.ZEN_MODE_OFF
+import android.provider.Settings.Secure.ZEN_DURATION_FOREVER
+import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
+import androidx.test.filters.SmallTest
+import com.android.settingslib.notification.EnableZenModeDialog
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Expandable
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.policy.ZenModeController
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.settings.FakeSettings
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() {
+
+ @Mock private lateinit var zenModeController: ZenModeController
+ @Mock private lateinit var userTracker: UserTracker
+ @Mock private lateinit var conditionUri: Uri
+ @Mock private lateinit var enableZenModeDialog: EnableZenModeDialog
+ @Captor private lateinit var spyZenMode: ArgumentCaptor<Int>
+ @Captor private lateinit var spyConditionId: ArgumentCaptor<Uri?>
+ private lateinit var settings: FakeSettings
+
+ private lateinit var underTest: DoNotDisturbQuickAffordanceConfig
+ private lateinit var testDispatcher: TestDispatcher
+ private lateinit var testScope: TestScope
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
+
+ settings = FakeSettings()
+
+ underTest = DoNotDisturbQuickAffordanceConfig(
+ context,
+ zenModeController,
+ settings,
+ userTracker,
+ testDispatcher,
+ conditionUri,
+ enableZenModeDialog,
+ )
+ }
+
+ @Test
+ fun `dnd not available - picker state hidden`() = testScope.runTest {
+ //given
+ whenever(zenModeController.isZenAvailable).thenReturn(false)
+
+ //when
+ val result = underTest.getPickerScreenState()
+
+ //then
+ assertEquals(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice, result)
+ }
+
+ @Test
+ fun `dnd available - picker state visible`() = testScope.runTest {
+ //given
+ whenever(zenModeController.isZenAvailable).thenReturn(true)
+
+ //when
+ val result = underTest.getPickerScreenState()
+
+ //then
+ assertEquals(KeyguardQuickAffordanceConfig.PickerScreenState.Default, result)
+ }
+
+ @Test
+ fun `onTriggered - dnd mode is not ZEN_MODE_OFF - set to ZEN_MODE_OFF`() = testScope.runTest {
+ //given
+ whenever(zenModeController.isZenAvailable).thenReturn(true)
+ whenever(zenModeController.zen).thenReturn(-1)
+ settings.putInt(Settings.Secure.ZEN_DURATION, -2)
+ collectLastValue(underTest.lockScreenState)
+ runCurrent()
+
+ //when
+ val result = underTest.onTriggered(null)
+ verify(zenModeController).setZen(spyZenMode.capture(), spyConditionId.capture(), eq(DoNotDisturbQuickAffordanceConfig.TAG))
+
+ //then
+ assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
+ assertEquals(ZEN_MODE_OFF, spyZenMode.value)
+ assertNull(spyConditionId.value)
+ }
+
+ @Test
+ fun `onTriggered - dnd mode is ZEN_MODE_OFF - setting is FOREVER - set zen with no condition`() = testScope.runTest {
+ //given
+ whenever(zenModeController.isZenAvailable).thenReturn(true)
+ whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+ settings.putInt(Settings.Secure.ZEN_DURATION, ZEN_DURATION_FOREVER)
+ collectLastValue(underTest.lockScreenState)
+ runCurrent()
+
+ //when
+ val result = underTest.onTriggered(null)
+ verify(zenModeController).setZen(spyZenMode.capture(), spyConditionId.capture(), eq(DoNotDisturbQuickAffordanceConfig.TAG))
+
+ //then
+ assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
+ assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, spyZenMode.value)
+ assertNull(spyConditionId.value)
+ }
+
+ @Test
+ fun `onTriggered - dnd mode is ZEN_MODE_OFF - setting is not FOREVER or PROMPT - set zen with condition`() = testScope.runTest {
+ //given
+ whenever(zenModeController.isZenAvailable).thenReturn(true)
+ whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+ settings.putInt(Settings.Secure.ZEN_DURATION, -900)
+ collectLastValue(underTest.lockScreenState)
+ runCurrent()
+
+ //when
+ val result = underTest.onTriggered(null)
+ verify(zenModeController).setZen(spyZenMode.capture(), spyConditionId.capture(), eq(DoNotDisturbQuickAffordanceConfig.TAG))
+
+ //then
+ assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result)
+ assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, spyZenMode.value)
+ assertEquals(conditionUri, spyConditionId.value)
+ }
+
+ @Test
+ fun `onTriggered - dnd mode is ZEN_MODE_OFF - setting is PROMPT - show dialog`() = testScope.runTest {
+ //given
+ val expandable: Expandable = mock()
+ whenever(zenModeController.isZenAvailable).thenReturn(true)
+ whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+ settings.putInt(Settings.Secure.ZEN_DURATION, ZEN_DURATION_PROMPT)
+ whenever(enableZenModeDialog.createDialog()).thenReturn(mock())
+ collectLastValue(underTest.lockScreenState)
+ runCurrent()
+
+ //when
+ val result = underTest.onTriggered(expandable)
+
+ //then
+ assertTrue(result is KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog)
+ assertEquals(expandable, (result as KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog).expandable)
+ }
+
+ @Test
+ fun `lockScreenState - dndAvailable starts as true - changes to false - State moves to Hidden`() = testScope.runTest {
+ //given
+ whenever(zenModeController.isZenAvailable).thenReturn(true)
+ val callbackCaptor: ArgumentCaptor<ZenModeController.Callback> = argumentCaptor()
+ val valueSnapshot = collectLastValue(underTest.lockScreenState)
+ val secondLastValue = valueSnapshot()
+ verify(zenModeController).addCallback(callbackCaptor.capture())
+
+ //when
+ callbackCaptor.value.onZenAvailableChanged(false)
+ val lastValue = valueSnapshot()
+
+ //then
+ assertTrue(secondLastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible)
+ assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
+ }
+
+ @Test
+ fun `lockScreenState - dndMode starts as ZEN_MODE_OFF - changes to not OFF - State moves to Visible`() = testScope.runTest {
+ //given
+ whenever(zenModeController.isZenAvailable).thenReturn(true)
+ whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+ val valueSnapshot = collectLastValue(underTest.lockScreenState)
+ val secondLastValue = valueSnapshot()
+ val callbackCaptor: ArgumentCaptor<ZenModeController.Callback> = argumentCaptor()
+ verify(zenModeController).addCallback(callbackCaptor.capture())
+
+ //when
+ callbackCaptor.value.onZenChanged(ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+ val lastValue = valueSnapshot()
+
+ //then
+ assertEquals(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ Icon.Resource(
+ R.drawable.qs_dnd_icon_off,
+ ContentDescription.Resource(R.string.dnd_is_off)
+ ),
+ ActivationState.Inactive
+ ),
+ secondLastValue,
+ )
+ assertEquals(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ Icon.Resource(
+ R.drawable.qs_dnd_icon_on,
+ ContentDescription.Resource(R.string.dnd_is_on)
+ ),
+ ActivationState.Active
+ ),
+ lastValue,
+ )
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
index 67091a9..3d65713 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
@@ -165,6 +165,10 @@
@Test
fun `remembers selections by user`() = runTest {
+ overrideResource(
+ R.array.config_keyguardQuickAffordanceDefaults,
+ arrayOf<String>(),
+ )
val slot1 = "slot_1"
val slot2 = "slot_2"
val affordance1 = "affordance_1"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index c40488a..c187a3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -114,6 +114,11 @@
userHandle = UserHandle.SYSTEM,
)
+ overrideResource(
+ R.array.config_keyguardQuickAffordanceDefaults,
+ arrayOf<String>(),
+ )
+
underTest =
KeyguardQuickAffordanceRepository(
appContext = context,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index 5deac19..563d44d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -28,6 +28,8 @@
import com.android.systemui.doze.DozeMachine
import com.android.systemui.doze.DozeTransitionCallback
import com.android.systemui.doze.DozeTransitionListener
+import com.android.systemui.dreams.DreamCallbackController
+import com.android.systemui.dreams.DreamCallbackController.DreamCallback
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
@@ -66,6 +68,7 @@
@Mock private lateinit var dozeTransitionListener: DozeTransitionListener
@Mock private lateinit var authController: AuthController
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+ @Mock private lateinit var dreamCallbackController: DreamCallbackController
private lateinit var underTest: KeyguardRepositoryImpl
@@ -83,6 +86,7 @@
keyguardUpdateMonitor,
dozeTransitionListener,
authController,
+ dreamCallbackController,
)
}
@@ -318,7 +322,7 @@
}
@Test
- fun isDreaming() =
+ fun isDreamingFromKeyguardUpdateMonitor() =
runTest(UnconfinedTestDispatcher()) {
whenever(keyguardUpdateMonitor.isDreaming()).thenReturn(false)
var latest: Boolean? = null
@@ -339,6 +343,26 @@
}
@Test
+ fun isDreamingFromDreamCallbackController() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(keyguardUpdateMonitor.isDreaming()).thenReturn(true)
+ var latest: Boolean? = null
+ val job = underTest.isDreaming.onEach { latest = it }.launchIn(this)
+
+ assertThat(latest).isTrue()
+
+ val listener =
+ withArgCaptor<DreamCallbackController.DreamCallback> {
+ verify(dreamCallbackController).addCallback(capture())
+ }
+
+ listener.onWakeUp()
+ assertThat(latest).isFalse()
+
+ job.cancel()
+ }
+
+ @Test
fun biometricUnlockState() =
runTest(UnconfinedTestDispatcher()) {
val values = mutableListOf<BiometricUnlockModel>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
index ce9c1da..5d2f0eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
@@ -16,13 +16,10 @@
package com.android.systemui.keyguard.data.repository
-import android.animation.AnimationHandler.AnimationFrameCallbackProvider
import android.animation.ValueAnimator
import android.util.Log
import android.util.Log.TerribleFailure
import android.util.Log.TerribleFailureHandler
-import android.view.Choreographer.FrameCallback
-import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Interpolators
@@ -32,22 +29,17 @@
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.util.KeyguardTransitionRunner
import com.google.common.truth.Truth.assertThat
import java.math.BigDecimal
import java.math.RoundingMode
import java.util.UUID
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.yield
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
import org.junit.After
-import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -60,12 +52,14 @@
private lateinit var underTest: KeyguardTransitionRepository
private lateinit var oldWtfHandler: TerribleFailureHandler
private lateinit var wtfHandler: WtfHandler
+ private lateinit var runner: KeyguardTransitionRunner
@Before
fun setUp() {
underTest = KeyguardTransitionRepositoryImpl()
wtfHandler = WtfHandler()
oldWtfHandler = Log.setWtfHandler(wtfHandler)
+ runner = KeyguardTransitionRunner(underTest)
}
@After
@@ -75,56 +69,37 @@
@Test
fun `startTransition runs animator to completion`() =
- runBlocking(IMMEDIATE) {
- val (animator, provider) = setupAnimator(this)
-
+ TestScope().runTest {
val steps = mutableListOf<TransitionStep>()
val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this)
- underTest.startTransition(TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, animator))
-
- val startTime = System.currentTimeMillis()
- while (animator.isRunning()) {
- yield()
- if (System.currentTimeMillis() - startTime > MAX_TEST_DURATION) {
- fail("Failed test due to excessive runtime of: $MAX_TEST_DURATION")
- }
- }
+ runner.startTransition(
+ this,
+ TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, getAnimator()),
+ maxFrames = 100
+ )
assertSteps(steps, listWithStep(BigDecimal(.1)), AOD, LOCKSCREEN)
-
job.cancel()
- provider.stop()
}
@Test
- @FlakyTest(bugId = 260213291)
- fun `starting second transition will cancel the first transition`() {
- runBlocking(IMMEDIATE) {
- val (animator, provider) = setupAnimator(this)
-
+ fun `starting second transition will cancel the first transition`() =
+ TestScope().runTest {
val steps = mutableListOf<TransitionStep>()
val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this)
-
- underTest.startTransition(TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, animator))
- // 3 yields(), alternating with the animator, results in a value 0.1, which can be
- // canceled and tested against
- yield()
- yield()
- yield()
+ runner.startTransition(
+ this,
+ TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, getAnimator()),
+ maxFrames = 3,
+ )
// Now start 2nd transition, which will interrupt the first
val job2 = underTest.transition(LOCKSCREEN, AOD).onEach { steps.add(it) }.launchIn(this)
- val (animator2, provider2) = setupAnimator(this)
- underTest.startTransition(TransitionInfo(OWNER_NAME, LOCKSCREEN, AOD, animator2))
-
- val startTime = System.currentTimeMillis()
- while (animator2.isRunning()) {
- yield()
- if (System.currentTimeMillis() - startTime > MAX_TEST_DURATION) {
- fail("Failed test due to excessive runtime of: $MAX_TEST_DURATION")
- }
- }
+ runner.startTransition(
+ this,
+ TransitionInfo(OWNER_NAME, LOCKSCREEN, AOD, getAnimator()),
+ )
val firstTransitionSteps = listWithStep(step = BigDecimal(.1), stop = BigDecimal(.1))
assertSteps(steps.subList(0, 4), firstTransitionSteps, AOD, LOCKSCREEN)
@@ -134,31 +109,25 @@
job.cancel()
job2.cancel()
- provider.stop()
- provider2.stop()
}
- }
@Test
fun `Null animator enables manual control with updateTransition`() =
- runBlocking(IMMEDIATE) {
+ TestScope().runTest {
val steps = mutableListOf<TransitionStep>()
val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this)
val uuid =
underTest.startTransition(
- TransitionInfo(
- ownerName = OWNER_NAME,
- from = AOD,
- to = LOCKSCREEN,
- animator = null,
- )
+ TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, animator = null)
)
+ runCurrent()
checkNotNull(uuid).let {
underTest.updateTransition(it, 0.5f, TransitionState.RUNNING)
underTest.updateTransition(it, 1f, TransitionState.FINISHED)
}
+ runCurrent()
assertThat(steps.size).isEqualTo(3)
assertThat(steps[0])
@@ -256,57 +225,11 @@
assertThat(wtfHandler.failed).isFalse()
}
- private fun setupAnimator(
- scope: CoroutineScope
- ): Pair<ValueAnimator, TestFrameCallbackProvider> {
- val animator =
- ValueAnimator().apply {
- setInterpolator(Interpolators.LINEAR)
- setDuration(ANIMATION_DURATION)
- }
-
- val provider = TestFrameCallbackProvider(animator, scope)
- provider.start()
-
- return Pair(animator, provider)
- }
-
- /** Gives direct control over ValueAnimator. See [AnimationHandler] */
- private class TestFrameCallbackProvider(
- private val animator: ValueAnimator,
- private val scope: CoroutineScope,
- ) : AnimationFrameCallbackProvider {
-
- private var frameCount = 1L
- private var frames = MutableStateFlow(Pair<Long, FrameCallback?>(0L, null))
- private var job: Job? = null
-
- fun start() {
- animator.getAnimationHandler().setProvider(this)
-
- job =
- scope.launch {
- frames.collect {
- // Delay is required for AnimationHandler to properly register a callback
- yield()
- val (frameNumber, callback) = it
- callback?.doFrame(frameNumber)
- }
- }
+ private fun getAnimator(): ValueAnimator {
+ return ValueAnimator().apply {
+ setInterpolator(Interpolators.LINEAR)
+ setDuration(10)
}
-
- fun stop() {
- job?.cancel()
- animator.getAnimationHandler().setProvider(null)
- }
-
- override fun postFrameCallback(cb: FrameCallback) {
- frames.value = Pair(frameCount++, cb)
- }
- override fun postCommitCallback(runnable: Runnable) {}
- override fun getFrameTime() = frameCount
- override fun getFrameDelay() = 1L
- override fun setFrameDelay(delay: Long) {}
}
private class WtfHandler : TerribleFailureHandler {
@@ -317,9 +240,6 @@
}
companion object {
- private const val MAX_TEST_DURATION = 100L
- private const val ANIMATION_DURATION = 10L
- private const val OWNER_NAME = "Test"
- private val IMMEDIATE = Dispatchers.Main.immediate
+ private const val OWNER_NAME = "KeyguardTransitionRunner"
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index 1c1f039..14b7c31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -23,6 +23,7 @@
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
@@ -214,6 +215,7 @@
@Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
@Mock private lateinit var expandable: Expandable
+ @Mock private lateinit var launchAnimator: DialogLaunchAnimator
private lateinit var underTest: KeyguardQuickAffordanceInteractor
@@ -308,6 +310,7 @@
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
},
repository = { quickAffordanceRepository },
+ launchAnimator = launchAnimator,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 11fe905..972919a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -20,9 +20,12 @@
import android.os.UserHandle
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.quickaffordance.BuiltInKeyguardQuickAffordanceKeys
@@ -49,14 +52,10 @@
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.runBlockingTest
-import kotlinx.coroutines.yield
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -75,9 +74,11 @@
@Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var launchAnimator: DialogLaunchAnimator
private lateinit var underTest: KeyguardQuickAffordanceInteractor
+ private lateinit var testScope: TestScope
private lateinit var repository: FakeKeyguardRepository
private lateinit var homeControls: FakeKeyguardQuickAffordanceConfig
private lateinit var quickAccessWallet: FakeKeyguardQuickAffordanceConfig
@@ -99,7 +100,8 @@
)
qrCodeScanner =
FakeKeyguardQuickAffordanceConfig(BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER)
- val scope = CoroutineScope(IMMEDIATE)
+ val testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
val localUserSelectionManager =
KeyguardQuickAffordanceLocalUserSelectionManager(
@@ -120,7 +122,7 @@
)
val remoteUserSelectionManager =
KeyguardQuickAffordanceRemoteUserSelectionManager(
- scope = scope,
+ scope = testScope.backgroundScope,
userTracker = userTracker,
clientFactory = FakeKeyguardQuickAffordanceProviderClientFactory(userTracker),
userHandle = UserHandle.SYSTEM,
@@ -128,14 +130,14 @@
val quickAffordanceRepository =
KeyguardQuickAffordanceRepository(
appContext = context,
- scope = scope,
+ scope = testScope.backgroundScope,
localUserSelectionManager = localUserSelectionManager,
remoteUserSelectionManager = remoteUserSelectionManager,
userTracker = userTracker,
legacySettingSyncer =
KeyguardQuickAffordanceLegacySettingSyncer(
- scope = scope,
- backgroundDispatcher = IMMEDIATE,
+ scope = testScope.backgroundScope,
+ backgroundDispatcher = testDispatcher,
secureSettings = FakeSettings(),
selectionsManager = localUserSelectionManager,
),
@@ -171,92 +173,81 @@
activityStarter = activityStarter,
featureFlags = featureFlags,
repository = { quickAffordanceRepository },
+ launchAnimator = launchAnimator,
)
}
@Test
- fun `quickAffordance - bottom start affordance is visible`() = runBlockingTest {
- val configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
- homeControls.setState(
- KeyguardQuickAffordanceConfig.LockScreenState.Visible(
- icon = ICON,
- activationState = ActivationState.Active,
+ fun `quickAffordance - bottom start affordance is visible`() =
+ testScope.runTest {
+ val configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
+ homeControls.setState(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon = ICON,
+ activationState = ActivationState.Active,
+ )
)
- )
- var latest: KeyguardQuickAffordanceModel? = null
- val job =
- underTest
- .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
- .onEach { latest = it }
- .launchIn(this)
- // The interactor has an onStart { emit(Hidden) } to cover for upstream configs that don't
- // produce an initial value. We yield to give the coroutine time to emit the first real
- // value from our config.
- yield()
+ val collectedValue =
+ collectLastValue(
+ underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
+ )
- assertThat(latest).isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
- val visibleModel = latest as KeyguardQuickAffordanceModel.Visible
- assertThat(visibleModel.configKey).isEqualTo(configKey)
- assertThat(visibleModel.icon).isEqualTo(ICON)
- assertThat(visibleModel.icon.contentDescription)
- .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
- assertThat(visibleModel.activationState).isEqualTo(ActivationState.Active)
- job.cancel()
- }
+ assertThat(collectedValue())
+ .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
+ val visibleModel = collectedValue() as KeyguardQuickAffordanceModel.Visible
+ assertThat(visibleModel.configKey).isEqualTo(configKey)
+ assertThat(visibleModel.icon).isEqualTo(ICON)
+ assertThat(visibleModel.icon.contentDescription)
+ .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
+ assertThat(visibleModel.activationState).isEqualTo(ActivationState.Active)
+ }
@Test
- fun `quickAffordance - bottom end affordance is visible`() = runBlockingTest {
- val configKey = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
- quickAccessWallet.setState(
- KeyguardQuickAffordanceConfig.LockScreenState.Visible(
- icon = ICON,
+ fun `quickAffordance - bottom end affordance is visible`() =
+ testScope.runTest {
+ val configKey = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
+ quickAccessWallet.setState(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon = ICON,
+ )
)
- )
- var latest: KeyguardQuickAffordanceModel? = null
- val job =
- underTest
- .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
- .onEach { latest = it }
- .launchIn(this)
- // The interactor has an onStart { emit(Hidden) } to cover for upstream configs that don't
- // produce an initial value. We yield to give the coroutine time to emit the first real
- // value from our config.
- yield()
+ val collectedValue =
+ collectLastValue(
+ underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
+ )
- assertThat(latest).isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
- val visibleModel = latest as KeyguardQuickAffordanceModel.Visible
- assertThat(visibleModel.configKey).isEqualTo(configKey)
- assertThat(visibleModel.icon).isEqualTo(ICON)
- assertThat(visibleModel.icon.contentDescription)
- .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
- assertThat(visibleModel.activationState).isEqualTo(ActivationState.NotSupported)
- job.cancel()
- }
+ assertThat(collectedValue())
+ .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
+ val visibleModel = collectedValue() as KeyguardQuickAffordanceModel.Visible
+ assertThat(visibleModel.configKey).isEqualTo(configKey)
+ assertThat(visibleModel.icon).isEqualTo(ICON)
+ assertThat(visibleModel.icon.contentDescription)
+ .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
+ assertThat(visibleModel.activationState).isEqualTo(ActivationState.NotSupported)
+ }
@Test
- fun `quickAffordance - bottom start affordance hidden while dozing`() = runBlockingTest {
- repository.setDozing(true)
- homeControls.setState(
- KeyguardQuickAffordanceConfig.LockScreenState.Visible(
- icon = ICON,
+ fun `quickAffordance - bottom start affordance hidden while dozing`() =
+ testScope.runTest {
+ repository.setDozing(true)
+ homeControls.setState(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon = ICON,
+ )
)
- )
- var latest: KeyguardQuickAffordanceModel? = null
- val job =
- underTest
- .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
- .onEach { latest = it }
- .launchIn(this)
- assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
- job.cancel()
- }
+ val collectedValue =
+ collectLastValue(
+ underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
+ )
+ assertThat(collectedValue()).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
+ }
@Test
fun `quickAffordance - bottom start affordance hidden when lockscreen is not showing`() =
- runBlockingTest {
+ testScope.runTest {
repository.setKeyguardShowing(false)
homeControls.setState(
KeyguardQuickAffordanceConfig.LockScreenState.Visible(
@@ -264,19 +255,50 @@
)
)
- var latest: KeyguardQuickAffordanceModel? = null
- val job =
- underTest
- .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
- .onEach { latest = it }
- .launchIn(this)
- assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
- job.cancel()
+ val collectedValue =
+ collectLastValue(
+ underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
+ )
+ assertThat(collectedValue()).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
+ }
+
+ @Test
+ fun `quickAffordanceAlwaysVisible - even when lock screen not showing and dozing`() =
+ testScope.runTest {
+ repository.setKeyguardShowing(false)
+ repository.setDozing(true)
+ val configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
+ homeControls.setState(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon = ICON,
+ activationState = ActivationState.Active,
+ )
+ )
+
+ val collectedValue =
+ collectLastValue(
+ underTest.quickAffordanceAlwaysVisible(
+ KeyguardQuickAffordancePosition.BOTTOM_START
+ )
+ )
+ assertThat(collectedValue())
+ .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
+ val visibleModel = collectedValue() as KeyguardQuickAffordanceModel.Visible
+ assertThat(visibleModel.configKey).isEqualTo(configKey)
+ assertThat(visibleModel.icon).isEqualTo(ICON)
+ assertThat(visibleModel.icon.contentDescription)
+ .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
+ assertThat(visibleModel.activationState).isEqualTo(ActivationState.Active)
}
@Test
fun select() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
+ overrideResource(
+ R.array.config_keyguardQuickAffordanceDefaults,
+ arrayOf<String>(),
+ )
+
featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
homeControls.setState(
KeyguardQuickAffordanceConfig.LockScreenState.Visible(icon = ICON)
@@ -296,23 +318,18 @@
)
)
- var startConfig: KeyguardQuickAffordanceModel? = null
- val job1 =
- underTest
- .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
- .onEach { startConfig = it }
- .launchIn(this)
- var endConfig: KeyguardQuickAffordanceModel? = null
- val job2 =
- underTest
- .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
- .onEach { endConfig = it }
- .launchIn(this)
+ val startConfig =
+ collectLastValue(
+ underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
+ )
+ val endConfig =
+ collectLastValue(
+ underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
+ )
underTest.select(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, homeControls.key)
- yield()
- yield()
- assertThat(startConfig)
+
+ assertThat(startConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Visible(
configKey =
@@ -322,7 +339,7 @@
activationState = ActivationState.NotSupported,
)
)
- assertThat(endConfig)
+ assertThat(endConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Hidden,
)
@@ -345,9 +362,8 @@
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
quickAccessWallet.key
)
- yield()
- yield()
- assertThat(startConfig)
+
+ assertThat(startConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Visible(
configKey =
@@ -357,7 +373,7 @@
activationState = ActivationState.NotSupported,
)
)
- assertThat(endConfig)
+ assertThat(endConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Hidden,
)
@@ -377,9 +393,8 @@
)
underTest.select(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END, qrCodeScanner.key)
- yield()
- yield()
- assertThat(startConfig)
+
+ assertThat(startConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Visible(
configKey =
@@ -389,7 +404,7 @@
activationState = ActivationState.NotSupported,
)
)
- assertThat(endConfig)
+ assertThat(endConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Visible(
configKey =
@@ -420,14 +435,11 @@
),
)
)
-
- job1.cancel()
- job2.cancel()
}
@Test
fun `unselect - one`() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
homeControls.setState(
KeyguardQuickAffordanceConfig.LockScreenState.Visible(icon = ICON)
@@ -439,34 +451,23 @@
KeyguardQuickAffordanceConfig.LockScreenState.Visible(icon = ICON)
)
- var startConfig: KeyguardQuickAffordanceModel? = null
- val job1 =
- underTest
- .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
- .onEach { startConfig = it }
- .launchIn(this)
- var endConfig: KeyguardQuickAffordanceModel? = null
- val job2 =
- underTest
- .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
- .onEach { endConfig = it }
- .launchIn(this)
+ val startConfig =
+ collectLastValue(
+ underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
+ )
+ val endConfig =
+ collectLastValue(
+ underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
+ )
underTest.select(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, homeControls.key)
- yield()
- yield()
underTest.select(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END, quickAccessWallet.key)
- yield()
- yield()
-
underTest.unselect(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, homeControls.key)
- yield()
- yield()
- assertThat(startConfig)
+ assertThat(startConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Hidden,
)
- assertThat(endConfig)
+ assertThat(endConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Visible(
configKey =
@@ -495,14 +496,12 @@
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
quickAccessWallet.key
)
- yield()
- yield()
- assertThat(startConfig)
+ assertThat(startConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Hidden,
)
- assertThat(endConfig)
+ assertThat(endConfig())
.isEqualTo(
KeyguardQuickAffordanceModel.Hidden,
)
@@ -513,14 +512,11 @@
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to emptyList(),
)
)
-
- job1.cancel()
- job2.cancel()
}
@Test
fun `unselect - all`() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
featureFlags.set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
homeControls.setState(
KeyguardQuickAffordanceConfig.LockScreenState.Visible(icon = ICON)
@@ -533,15 +529,8 @@
)
underTest.select(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, homeControls.key)
- yield()
- yield()
underTest.select(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END, quickAccessWallet.key)
- yield()
- yield()
-
underTest.unselect(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, null)
- yield()
- yield()
assertThat(underTest.getSelections())
.isEqualTo(
@@ -562,8 +551,6 @@
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
null,
)
- yield()
- yield()
assertThat(underTest.getSelections())
.isEqualTo(
@@ -584,6 +571,5 @@
)
}
private const val CONTENT_DESCRIPTION_RESOURCE_ID = 1337
- private val IMMEDIATE = Dispatchers.Main.immediate
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
new file mode 100644
index 0000000..a6cf840
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.domain.interactor
+
+import android.animation.ValueAnimator
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositoryImpl
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionInfo
+import com.android.systemui.keyguard.shared.model.WakeSleepReason
+import com.android.systemui.keyguard.shared.model.WakefulnessModel
+import com.android.systemui.keyguard.shared.model.WakefulnessState
+import com.android.systemui.keyguard.util.KeyguardTransitionRunner
+import com.android.systemui.shade.data.repository.FakeShadeRepository
+import com.android.systemui.shade.data.repository.ShadeRepository
+import com.android.systemui.util.mockito.withArgCaptor
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.cancelChildren
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+/**
+ * Class for testing user journeys through the interactors. They will all be activated during setup,
+ * to ensure the expected transitions are still triggered.
+ */
+@SmallTest
+@RunWith(JUnit4::class)
+class KeyguardTransitionScenariosTest : SysuiTestCase() {
+ private lateinit var testScope: TestScope
+
+ private lateinit var keyguardRepository: FakeKeyguardRepository
+ private lateinit var shadeRepository: ShadeRepository
+
+ // Used to issue real transition steps for test input
+ private lateinit var runner: KeyguardTransitionRunner
+ private lateinit var transitionRepository: KeyguardTransitionRepository
+
+ // Used to verify transition requests for test output
+ @Mock private lateinit var mockTransitionRepository: KeyguardTransitionRepository
+
+ private lateinit var lockscreenBouncerTransitionInteractor:
+ LockscreenBouncerTransitionInteractor
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ testScope = TestScope()
+
+ keyguardRepository = FakeKeyguardRepository()
+ shadeRepository = FakeShadeRepository()
+
+ /* Used to issue full transition steps, to better simulate a real device */
+ transitionRepository = KeyguardTransitionRepositoryImpl()
+ runner = KeyguardTransitionRunner(transitionRepository)
+
+ lockscreenBouncerTransitionInteractor =
+ LockscreenBouncerTransitionInteractor(
+ scope = testScope,
+ keyguardInteractor = KeyguardInteractor(keyguardRepository),
+ shadeRepository = shadeRepository,
+ keyguardTransitionRepository = mockTransitionRepository,
+ keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+ )
+ lockscreenBouncerTransitionInteractor.start()
+ }
+
+ @Test
+ fun `LOCKSCREEN to BOUNCER via bouncer showing call`() =
+ testScope.runTest {
+ // GIVEN a device that has at least woken up
+ keyguardRepository.setWakefulnessModel(startingToWake())
+ runCurrent()
+
+ // GIVEN a transition has run to LOCKSCREEN
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.OFF,
+ to = KeyguardState.LOCKSCREEN,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+
+ // WHEN the bouncer is set to show
+ keyguardRepository.setBouncerShowing(true)
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to BOUNCER should occur
+ assertThat(info.ownerName).isEqualTo("LockscreenBouncerTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
+ assertThat(info.to).isEqualTo(KeyguardState.BOUNCER)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ private fun startingToWake() =
+ WakefulnessModel(
+ WakefulnessState.STARTING_TO_WAKE,
+ true,
+ WakeSleepReason.OTHER,
+ WakeSleepReason.OTHER
+ )
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
new file mode 100644
index 0000000..81950f1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.DreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.Companion.DREAM_OVERLAY_ALPHA
+import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.Companion.DREAM_OVERLAY_TRANSLATION_Y
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
+ private lateinit var underTest: DreamingToLockscreenTransitionViewModel
+ private lateinit var repository: FakeKeyguardTransitionRepository
+
+ @Before
+ fun setUp() {
+ repository = FakeKeyguardTransitionRepository()
+ val interactor = KeyguardTransitionInteractor(repository)
+ underTest = DreamingToLockscreenTransitionViewModel(interactor)
+ }
+
+ @Test
+ fun dreamOverlayTranslationY() =
+ runTest(UnconfinedTestDispatcher()) {
+ val values = mutableListOf<Float>()
+
+ val pixels = 100
+ val job =
+ underTest.dreamOverlayTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+
+ repository.sendTransitionStep(step(0f))
+ repository.sendTransitionStep(step(0.3f))
+ repository.sendTransitionStep(step(0.5f))
+ repository.sendTransitionStep(step(1f))
+
+ // Only two values should be present, since the dream overlay runs for a small fraction
+ // of
+ // the overall animation time
+ assertThat(values.size).isEqualTo(2)
+ assertThat(values[0])
+ .isEqualTo(
+ EMPHASIZED_ACCELERATE.getInterpolation(
+ animValue(0f, DREAM_OVERLAY_TRANSLATION_Y)
+ ) * pixels
+ )
+ assertThat(values[1])
+ .isEqualTo(
+ EMPHASIZED_ACCELERATE.getInterpolation(
+ animValue(0.3f, DREAM_OVERLAY_TRANSLATION_Y)
+ ) * pixels
+ )
+
+ job.cancel()
+ }
+
+ @Test
+ fun dreamOverlayFadeOut() =
+ runTest(UnconfinedTestDispatcher()) {
+ val values = mutableListOf<Float>()
+
+ val job = underTest.dreamOverlayAlpha.onEach { values.add(it) }.launchIn(this)
+
+ repository.sendTransitionStep(step(0f))
+ repository.sendTransitionStep(step(0.1f))
+ repository.sendTransitionStep(step(0.5f))
+ repository.sendTransitionStep(step(1f))
+
+ // Only two values should be present, since the dream overlay runs for a small fraction
+ // of
+ // the overall animation time
+ assertThat(values.size).isEqualTo(2)
+ assertThat(values[0]).isEqualTo(1f - animValue(0f, DREAM_OVERLAY_ALPHA))
+ assertThat(values[1]).isEqualTo(1f - animValue(0.1f, DREAM_OVERLAY_ALPHA))
+
+ job.cancel()
+ }
+
+ private fun animValue(stepValue: Float, params: AnimationParams): Float {
+ val totalDuration = TO_LOCKSCREEN_DURATION
+ val startValue = (params.startTime / totalDuration).toFloat()
+
+ val multiplier = (totalDuration / params.duration).toFloat()
+ return (stepValue - startValue) * multiplier
+ }
+
+ private fun step(value: Float): TransitionStep {
+ return TransitionStep(
+ from = KeyguardState.DREAMING,
+ to = KeyguardState.LOCKSCREEN,
+ value = value,
+ transitionState = TransitionState.RUNNING,
+ ownerName = "DreamingToLockscreenTransitionViewModelTest"
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index 83a5d0e..a2c2f71 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -21,8 +21,10 @@
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.doze.util.BurnInHelperWrapper
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
@@ -44,20 +46,21 @@
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
import kotlin.math.max
import kotlin.math.min
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
-import kotlinx.coroutines.yield
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -67,9 +70,9 @@
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(JUnit4::class)
class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
@@ -80,9 +83,11 @@
@Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var launchAnimator: DialogLaunchAnimator
private lateinit var underTest: KeyguardBottomAreaViewModel
+ private lateinit var testScope: TestScope
private lateinit var repository: FakeKeyguardRepository
private lateinit var registry: FakeKeyguardQuickAffordanceRegistry
private lateinit var homeControlsQuickAffordanceConfig: FakeKeyguardQuickAffordanceConfig
@@ -123,7 +128,8 @@
whenever(userTracker.userHandle).thenReturn(mock())
whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
.thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
- val scope = CoroutineScope(IMMEDIATE)
+ val testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
val localUserSelectionManager =
KeyguardQuickAffordanceLocalUserSelectionManager(
context = context,
@@ -143,7 +149,7 @@
)
val remoteUserSelectionManager =
KeyguardQuickAffordanceRemoteUserSelectionManager(
- scope = scope,
+ scope = testScope.backgroundScope,
userTracker = userTracker,
clientFactory = FakeKeyguardQuickAffordanceProviderClientFactory(userTracker),
userHandle = UserHandle.SYSTEM,
@@ -151,14 +157,14 @@
val quickAffordanceRepository =
KeyguardQuickAffordanceRepository(
appContext = context,
- scope = scope,
+ scope = testScope.backgroundScope,
localUserSelectionManager = localUserSelectionManager,
remoteUserSelectionManager = remoteUserSelectionManager,
userTracker = userTracker,
legacySettingSyncer =
KeyguardQuickAffordanceLegacySettingSyncer(
- scope = scope,
- backgroundDispatcher = IMMEDIATE,
+ scope = testScope.backgroundScope,
+ backgroundDispatcher = testDispatcher,
secureSettings = FakeSettings(),
selectionsManager = localUserSelectionManager,
),
@@ -187,6 +193,7 @@
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
},
repository = { quickAffordanceRepository },
+ launchAnimator = launchAnimator,
),
bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
burnInHelperWrapper = burnInHelperWrapper,
@@ -194,366 +201,394 @@
}
@Test
- fun `startButton - present - visible model - starts activity on click`() = runBlockingTest {
- repository.setKeyguardShowing(true)
- var latest: KeyguardQuickAffordanceViewModel? = null
- val job = underTest.startButton.onEach { latest = it }.launchIn(this)
+ fun `startButton - present - visible model - starts activity on click`() =
+ testScope.runTest {
+ repository.setKeyguardShowing(true)
+ val latest = collectLastValue(underTest.startButton)
- val testConfig =
- TestConfig(
- isVisible = true,
- isClickable = true,
- isActivated = true,
- icon = mock(),
- canShowWhileLocked = false,
- intent = Intent("action"),
- )
- val configKey =
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
- testConfig = testConfig,
- )
-
- assertQuickAffordanceViewModel(
- viewModel = latest,
- testConfig = testConfig,
- configKey = configKey,
- )
- job.cancel()
- }
-
- @Test
- fun `endButton - present - visible model - do nothing on click`() = runBlockingTest {
- repository.setKeyguardShowing(true)
- var latest: KeyguardQuickAffordanceViewModel? = null
- val job = underTest.endButton.onEach { latest = it }.launchIn(this)
-
- val config =
- TestConfig(
- isVisible = true,
- isClickable = true,
- icon = mock(),
- canShowWhileLocked = false,
- intent = null, // This will cause it to tell the system that the click was handled.
- )
- val configKey =
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_END,
- testConfig = config,
- )
-
- assertQuickAffordanceViewModel(
- viewModel = latest,
- testConfig = config,
- configKey = configKey,
- )
- job.cancel()
- }
-
- @Test
- fun `startButton - not present - model is hidden`() = runBlockingTest {
- var latest: KeyguardQuickAffordanceViewModel? = null
- val job = underTest.startButton.onEach { latest = it }.launchIn(this)
-
- val config =
- TestConfig(
- isVisible = false,
- )
- val configKey =
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
- testConfig = config,
- )
-
- assertQuickAffordanceViewModel(
- viewModel = latest,
- testConfig = config,
- configKey = configKey,
- )
- job.cancel()
- }
-
- @Test
- fun animateButtonReveal() = runBlockingTest {
- repository.setKeyguardShowing(true)
- val testConfig =
- TestConfig(
- isVisible = true,
- isClickable = true,
- icon = mock(),
- canShowWhileLocked = false,
- intent = Intent("action"),
- )
-
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
- testConfig = testConfig,
- )
-
- val values = mutableListOf<Boolean>()
- val job = underTest.startButton.onEach { values.add(it.animateReveal) }.launchIn(this)
-
- repository.setAnimateDozingTransitions(true)
- yield()
- repository.setAnimateDozingTransitions(false)
- yield()
-
- // Note the extra false value in the beginning. This is to cover for the initial value
- // inserted by the quick affordance interactor which it does to cover for config
- // implementations that don't emit an initial value.
- assertThat(values).isEqualTo(listOf(false, false, true, false))
- job.cancel()
- }
-
- @Test
- fun isOverlayContainerVisible() = runBlockingTest {
- val values = mutableListOf<Boolean>()
- val job = underTest.isOverlayContainerVisible.onEach(values::add).launchIn(this)
-
- repository.setDozing(true)
- repository.setDozing(false)
-
- assertThat(values).isEqualTo(listOf(true, false, true))
- job.cancel()
- }
-
- @Test
- fun alpha() = runBlockingTest {
- val values = mutableListOf<Float>()
- val job = underTest.alpha.onEach(values::add).launchIn(this)
-
- repository.setBottomAreaAlpha(0.1f)
- repository.setBottomAreaAlpha(0.5f)
- repository.setBottomAreaAlpha(0.2f)
- repository.setBottomAreaAlpha(0f)
-
- assertThat(values).isEqualTo(listOf(1f, 0.1f, 0.5f, 0.2f, 0f))
- job.cancel()
- }
-
- @Test
- fun isIndicationAreaPadded() = runBlockingTest {
- repository.setKeyguardShowing(true)
- val values = mutableListOf<Boolean>()
- val job = underTest.isIndicationAreaPadded.onEach(values::add).launchIn(this)
-
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
- testConfig =
+ val testConfig =
TestConfig(
isVisible = true,
isClickable = true,
+ isActivated = true,
icon = mock(),
- canShowWhileLocked = true,
+ canShowWhileLocked = false,
+ intent = Intent("action"),
)
- )
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_END,
- testConfig =
+ val configKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig = testConfig,
+ )
+
+ assertQuickAffordanceViewModel(
+ viewModel = latest(),
+ testConfig = testConfig,
+ configKey = configKey,
+ )
+ }
+
+ @Test
+ fun `startButton - in preview mode - visible even when keyguard not showing`() =
+ testScope.runTest {
+ underTest.enablePreviewMode(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
+ repository.setKeyguardShowing(false)
+ val latest = collectLastValue(underTest.startButton)
+
+ val icon: Icon = mock()
+ val configKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = true,
+ isActivated = true,
+ icon = icon,
+ canShowWhileLocked = false,
+ intent = Intent("action"),
+ ),
+ )
+
+ assertQuickAffordanceViewModel(
+ viewModel = latest(),
+ testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = false,
+ isActivated = true,
+ icon = icon,
+ canShowWhileLocked = false,
+ intent = Intent("action"),
+ ),
+ configKey = configKey,
+ )
+ assertThat(latest()?.isSelected).isTrue()
+ }
+
+ @Test
+ fun `endButton - present - visible model - do nothing on click`() =
+ testScope.runTest {
+ repository.setKeyguardShowing(true)
+ val latest = collectLastValue(underTest.endButton)
+
+ val config =
TestConfig(
isVisible = true,
isClickable = true,
icon = mock(),
canShowWhileLocked = false,
+ intent =
+ null, // This will cause it to tell the system that the click was handled.
)
- )
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
- testConfig =
+ val configKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_END,
+ testConfig = config,
+ )
+
+ assertQuickAffordanceViewModel(
+ viewModel = latest(),
+ testConfig = config,
+ configKey = configKey,
+ )
+ }
+
+ @Test
+ fun `startButton - not present - model is hidden`() =
+ testScope.runTest {
+ val latest = collectLastValue(underTest.startButton)
+
+ val config =
TestConfig(
isVisible = false,
)
- )
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_END,
- testConfig =
+ val configKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig = config,
+ )
+
+ assertQuickAffordanceViewModel(
+ viewModel = latest(),
+ testConfig = config,
+ configKey = configKey,
+ )
+ }
+
+ @Test
+ fun animateButtonReveal() =
+ testScope.runTest {
+ repository.setKeyguardShowing(true)
+ val testConfig =
TestConfig(
- isVisible = false,
+ isVisible = true,
+ isClickable = true,
+ icon = mock(),
+ canShowWhileLocked = false,
+ intent = Intent("action"),
)
- )
- assertThat(values)
- .isEqualTo(
- listOf(
- // Initially, no button is visible so the indication area is not padded.
- false,
- // Once we add the first visible button, the indication area becomes padded.
- // This
- // continues to be true after we add the second visible button and even after we
- // make the first button not visible anymore.
- true,
- // Once both buttons are not visible, the indication area is, again, not padded.
- false,
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig = testConfig,
+ )
+
+ val value = collectLastValue(underTest.startButton.map { it.animateReveal })
+
+ assertThat(value()).isFalse()
+ repository.setAnimateDozingTransitions(true)
+ assertThat(value()).isTrue()
+ repository.setAnimateDozingTransitions(false)
+ assertThat(value()).isFalse()
+ }
+
+ @Test
+ fun isOverlayContainerVisible() =
+ testScope.runTest {
+ val value = collectLastValue(underTest.isOverlayContainerVisible)
+
+ assertThat(value()).isTrue()
+ repository.setDozing(true)
+ assertThat(value()).isFalse()
+ repository.setDozing(false)
+ assertThat(value()).isTrue()
+ }
+
+ @Test
+ fun alpha() =
+ testScope.runTest {
+ val value = collectLastValue(underTest.alpha)
+
+ assertThat(value()).isEqualTo(1f)
+ repository.setBottomAreaAlpha(0.1f)
+ assertThat(value()).isEqualTo(0.1f)
+ repository.setBottomAreaAlpha(0.5f)
+ assertThat(value()).isEqualTo(0.5f)
+ repository.setBottomAreaAlpha(0.2f)
+ assertThat(value()).isEqualTo(0.2f)
+ repository.setBottomAreaAlpha(0f)
+ assertThat(value()).isEqualTo(0f)
+ }
+
+ @Test
+ fun `alpha - in preview mode - does not change`() =
+ testScope.runTest {
+ underTest.enablePreviewMode(null)
+ val value = collectLastValue(underTest.alpha)
+
+ assertThat(value()).isEqualTo(1f)
+ repository.setBottomAreaAlpha(0.1f)
+ assertThat(value()).isEqualTo(1f)
+ repository.setBottomAreaAlpha(0.5f)
+ assertThat(value()).isEqualTo(1f)
+ repository.setBottomAreaAlpha(0.2f)
+ assertThat(value()).isEqualTo(1f)
+ repository.setBottomAreaAlpha(0f)
+ assertThat(value()).isEqualTo(1f)
+ }
+
+ @Test
+ fun isIndicationAreaPadded() =
+ testScope.runTest {
+ repository.setKeyguardShowing(true)
+ val value = collectLastValue(underTest.isIndicationAreaPadded)
+
+ assertThat(value()).isFalse()
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = true,
+ icon = mock(),
+ canShowWhileLocked = true,
+ )
+ )
+ assertThat(value()).isTrue()
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_END,
+ testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = true,
+ icon = mock(),
+ canShowWhileLocked = false,
+ )
+ )
+ assertThat(value()).isTrue()
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig =
+ TestConfig(
+ isVisible = false,
+ )
+ )
+ assertThat(value()).isTrue()
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_END,
+ testConfig =
+ TestConfig(
+ isVisible = false,
+ )
+ )
+ assertThat(value()).isFalse()
+ }
+
+ @Test
+ fun indicationAreaTranslationX() =
+ testScope.runTest {
+ val value = collectLastValue(underTest.indicationAreaTranslationX)
+
+ assertThat(value()).isEqualTo(0f)
+ repository.setClockPosition(100, 100)
+ assertThat(value()).isEqualTo(100f)
+ repository.setClockPosition(200, 100)
+ assertThat(value()).isEqualTo(200f)
+ repository.setClockPosition(200, 200)
+ assertThat(value()).isEqualTo(200f)
+ repository.setClockPosition(300, 100)
+ assertThat(value()).isEqualTo(300f)
+ }
+
+ @Test
+ fun indicationAreaTranslationY() =
+ testScope.runTest {
+ val value =
+ collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET))
+
+ // Negative 0 - apparently there's a difference in floating point arithmetic - FML
+ assertThat(value()).isEqualTo(-0f)
+ val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f)
+ assertThat(value()).isEqualTo(expected1)
+ val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f)
+ assertThat(value()).isEqualTo(expected2)
+ val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f)
+ assertThat(value()).isEqualTo(expected3)
+ val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f)
+ assertThat(value()).isEqualTo(expected4)
+ }
+
+ @Test
+ fun `isClickable - true when alpha at threshold`() =
+ testScope.runTest {
+ repository.setKeyguardShowing(true)
+ repository.setBottomAreaAlpha(
+ KeyguardBottomAreaViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD
+ )
+
+ val testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = true,
+ icon = mock(),
+ canShowWhileLocked = false,
+ intent = Intent("action"),
)
- )
- job.cancel()
- }
+ val configKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig = testConfig,
+ )
- @Test
- fun indicationAreaTranslationX() = runBlockingTest {
- val values = mutableListOf<Float>()
- val job = underTest.indicationAreaTranslationX.onEach(values::add).launchIn(this)
+ val latest = collectLastValue(underTest.startButton)
- repository.setClockPosition(100, 100)
- repository.setClockPosition(200, 100)
- repository.setClockPosition(200, 200)
- repository.setClockPosition(300, 100)
-
- assertThat(values).isEqualTo(listOf(0f, 100f, 200f, 300f))
- job.cancel()
- }
-
- @Test
- fun indicationAreaTranslationY() = runBlockingTest {
- val values = mutableListOf<Float>()
- val job =
- underTest
- .indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET)
- .onEach(values::add)
- .launchIn(this)
-
- val expectedTranslationValues =
- listOf(
- -0f, // Negative 0 - apparently there's a difference in floating point arithmetic -
- // FML
- setDozeAmountAndCalculateExpectedTranslationY(0.1f),
- setDozeAmountAndCalculateExpectedTranslationY(0.2f),
- setDozeAmountAndCalculateExpectedTranslationY(0.5f),
- setDozeAmountAndCalculateExpectedTranslationY(1f),
- )
-
- assertThat(values).isEqualTo(expectedTranslationValues)
- job.cancel()
- }
-
- @Test
- fun `isClickable - true when alpha at threshold`() = runBlockingTest {
- repository.setKeyguardShowing(true)
- repository.setBottomAreaAlpha(
- KeyguardBottomAreaViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD
- )
-
- val testConfig =
- TestConfig(
- isVisible = true,
- isClickable = true,
- icon = mock(),
- canShowWhileLocked = false,
- intent = Intent("action"),
- )
- val configKey =
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ assertQuickAffordanceViewModel(
+ viewModel = latest(),
testConfig = testConfig,
+ configKey = configKey,
)
-
- var latest: KeyguardQuickAffordanceViewModel? = null
- val job = underTest.startButton.onEach { latest = it }.launchIn(this)
- // The interactor has an onStart { emit(Hidden) } to cover for upstream configs that don't
- // produce an initial value. We yield to give the coroutine time to emit the first real
- // value from our config.
- yield()
-
- assertQuickAffordanceViewModel(
- viewModel = latest,
- testConfig = testConfig,
- configKey = configKey,
- )
- job.cancel()
- }
+ }
@Test
- fun `isClickable - true when alpha above threshold`() = runBlockingTest {
- repository.setKeyguardShowing(true)
- var latest: KeyguardQuickAffordanceViewModel? = null
- val job = underTest.startButton.onEach { latest = it }.launchIn(this)
- repository.setBottomAreaAlpha(
- min(1f, KeyguardBottomAreaViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD + 0.1f),
- )
-
- val testConfig =
- TestConfig(
- isVisible = true,
- isClickable = true,
- icon = mock(),
- canShowWhileLocked = false,
- intent = Intent("action"),
+ fun `isClickable - true when alpha above threshold`() =
+ testScope.runTest {
+ repository.setKeyguardShowing(true)
+ val latest = collectLastValue(underTest.startButton)
+ repository.setBottomAreaAlpha(
+ min(1f, KeyguardBottomAreaViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD + 0.1f),
)
- val configKey =
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
+
+ val testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = true,
+ icon = mock(),
+ canShowWhileLocked = false,
+ intent = Intent("action"),
+ )
+ val configKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig = testConfig,
+ )
+
+ assertQuickAffordanceViewModel(
+ viewModel = latest(),
testConfig = testConfig,
+ configKey = configKey,
)
-
- assertQuickAffordanceViewModel(
- viewModel = latest,
- testConfig = testConfig,
- configKey = configKey,
- )
- job.cancel()
- }
+ }
@Test
- fun `isClickable - false when alpha below threshold`() = runBlockingTest {
- repository.setKeyguardShowing(true)
- var latest: KeyguardQuickAffordanceViewModel? = null
- val job = underTest.startButton.onEach { latest = it }.launchIn(this)
- repository.setBottomAreaAlpha(
- max(0f, KeyguardBottomAreaViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD - 0.1f),
- )
-
- val testConfig =
- TestConfig(
- isVisible = true,
- isClickable = false,
- icon = mock(),
- canShowWhileLocked = false,
- intent = Intent("action"),
+ fun `isClickable - false when alpha below threshold`() =
+ testScope.runTest {
+ repository.setKeyguardShowing(true)
+ val latest = collectLastValue(underTest.startButton)
+ repository.setBottomAreaAlpha(
+ max(0f, KeyguardBottomAreaViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD - 0.1f),
)
- val configKey =
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
+
+ val testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = false,
+ icon = mock(),
+ canShowWhileLocked = false,
+ intent = Intent("action"),
+ )
+ val configKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig = testConfig,
+ )
+
+ assertQuickAffordanceViewModel(
+ viewModel = latest(),
testConfig = testConfig,
+ configKey = configKey,
)
-
- assertQuickAffordanceViewModel(
- viewModel = latest,
- testConfig = testConfig,
- configKey = configKey,
- )
- job.cancel()
- }
+ }
@Test
- fun `isClickable - false when alpha at zero`() = runBlockingTest {
- repository.setKeyguardShowing(true)
- var latest: KeyguardQuickAffordanceViewModel? = null
- val job = underTest.startButton.onEach { latest = it }.launchIn(this)
- repository.setBottomAreaAlpha(0f)
+ fun `isClickable - false when alpha at zero`() =
+ testScope.runTest {
+ repository.setKeyguardShowing(true)
+ val latest = collectLastValue(underTest.startButton)
+ repository.setBottomAreaAlpha(0f)
- val testConfig =
- TestConfig(
- isVisible = true,
- isClickable = false,
- icon = mock(),
- canShowWhileLocked = false,
- intent = Intent("action"),
- )
- val configKey =
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ val testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = false,
+ icon = mock(),
+ canShowWhileLocked = false,
+ intent = Intent("action"),
+ )
+ val configKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig = testConfig,
+ )
+
+ assertQuickAffordanceViewModel(
+ viewModel = latest(),
testConfig = testConfig,
+ configKey = configKey,
)
+ }
- assertQuickAffordanceViewModel(
- viewModel = latest,
- testConfig = testConfig,
- configKey = configKey,
- )
- job.cancel()
- }
-
- private suspend fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float {
+ private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float {
repository.setDozeAmount(dozeAmount)
return dozeAmount * (RETURNED_BURN_IN_OFFSET - DEFAULT_BURN_IN_OFFSET)
}
@@ -583,7 +618,6 @@
when (testConfig.isActivated) {
true -> ActivationState.Active
false -> ActivationState.Inactive
- null -> ActivationState.NotSupported
}
)
} else {
@@ -636,6 +670,5 @@
companion object {
private const val DEFAULT_BURN_IN_OFFSET = 5
private const val RETURNED_BURN_IN_OFFSET = 3
- private val IMMEDIATE = Dispatchers.Main.immediate
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRunner.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRunner.kt
new file mode 100644
index 0000000..c88f84a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRunner.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.util
+
+import android.animation.AnimationHandler.AnimationFrameCallbackProvider
+import android.animation.ValueAnimator
+import android.view.Choreographer.FrameCallback
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.TransitionInfo
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import org.junit.Assert.fail
+
+/**
+ * Gives direct control over ValueAnimator, in order to make transition tests deterministic. See
+ * [AnimationHandler]. Animators are required to be run on the main thread, so dispatch accordingly.
+ */
+class KeyguardTransitionRunner(
+ val repository: KeyguardTransitionRepository,
+) : AnimationFrameCallbackProvider {
+
+ private var frameCount = 1L
+ private var frames = MutableStateFlow(Pair<Long, FrameCallback?>(0L, null))
+ private var job: Job? = null
+ private var isTerminated = false
+
+ /**
+ * For transitions being directed by an animator. Will control the number of frames being
+ * generated so the values are deterministic.
+ */
+ suspend fun startTransition(scope: CoroutineScope, info: TransitionInfo, maxFrames: Int = 100) {
+ // AnimationHandler uses ThreadLocal storage, and ValueAnimators MUST start from main
+ // thread
+ withContext(Dispatchers.Main) {
+ info.animator!!.getAnimationHandler().setProvider(this@KeyguardTransitionRunner)
+ }
+
+ job =
+ scope.launch {
+ frames.collect {
+ val (frameNumber, callback) = it
+
+ isTerminated = frameNumber >= maxFrames
+ if (!isTerminated) {
+ withContext(Dispatchers.Main) { callback?.doFrame(frameNumber) }
+ }
+ }
+ }
+ withContext(Dispatchers.Main) { repository.startTransition(info) }
+
+ waitUntilComplete(info.animator!!)
+ }
+
+ suspend private fun waitUntilComplete(animator: ValueAnimator) {
+ withContext(Dispatchers.Main) {
+ val startTime = System.currentTimeMillis()
+ while (!isTerminated && animator.isRunning()) {
+ delay(1)
+ if (System.currentTimeMillis() - startTime > MAX_TEST_DURATION) {
+ fail("Failed test due to excessive runtime of: $MAX_TEST_DURATION")
+ }
+ }
+
+ animator.getAnimationHandler().setProvider(null)
+ }
+
+ job?.cancel()
+ }
+
+ override fun postFrameCallback(cb: FrameCallback) {
+ frames.value = Pair(frameCount++, cb)
+ }
+ override fun postCommitCallback(runnable: Runnable) {}
+ override fun getFrameTime() = frameCount
+ override fun getFrameDelay() = 1L
+ override fun setFrameDelay(delay: Long) {}
+
+ companion object {
+ private const val MAX_TEST_DURATION = 100L
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index 71c300c..b16a39f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -102,6 +102,8 @@
private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
+ private MediaItem mMediaItem1 = mock(MediaItem.class);
+ private MediaItem mMediaItem2 = mock(MediaItem.class);
private NearbyDevice mNearbyDevice1 = mock(NearbyDevice.class);
private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
@@ -125,6 +127,7 @@
private LocalMediaManager mLocalMediaManager;
private List<MediaController> mMediaControllers = new ArrayList<>();
private List<MediaDevice> mMediaDevices = new ArrayList<>();
+ private List<MediaItem> mMediaItemList = new ArrayList<>();
private List<NearbyDevice> mNearbyDevices = new ArrayList<>();
private MediaDescription mMediaDescription;
private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
@@ -157,6 +160,11 @@
when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
mMediaDevices.add(mMediaDevice1);
mMediaDevices.add(mMediaDevice2);
+ when(mMediaItem1.getMediaDevice()).thenReturn(Optional.of(mMediaDevice1));
+ when(mMediaItem2.getMediaDevice()).thenReturn(Optional.of(mMediaDevice2));
+ mMediaItemList.add(mMediaItem1);
+ mMediaItemList.add(mMediaItem2);
+
when(mNearbyDevice1.getMediaRoute2Id()).thenReturn(TEST_DEVICE_1_ID);
when(mNearbyDevice1.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
@@ -314,6 +322,18 @@
}
@Test
+ public void advanced_onDeviceListUpdate_isRefreshing_updatesNeedRefreshToTrue() {
+ when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+ mMediaOutputController.start(mCb);
+ reset(mCb);
+ mMediaOutputController.mIsRefreshing = true;
+
+ mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+
+ assertThat(mMediaOutputController.mNeedRefresh).isTrue();
+ }
+
+ @Test
public void cancelMuteAwaitConnection_cancelsWithMediaManager() {
when(mAudioManager.getMutingExpectedDevice()).thenReturn(mock(AudioDeviceAttributes.class));
mMediaOutputController.start(mCb);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
index e009e86..0e7bf8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
@@ -22,6 +22,7 @@
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogcatEchoTracker
+import com.android.systemui.temporarydisplay.TemporaryViewInfo
import com.google.common.truth.Truth.assertThat
import java.io.PrintWriter
import java.io.StringWriter
@@ -33,7 +34,7 @@
class MediaTttLoggerTest : SysuiTestCase() {
private lateinit var buffer: LogBuffer
- private lateinit var logger: MediaTttLogger
+ private lateinit var logger: MediaTttLogger<TemporaryViewInfo>
@Before
fun setUp () {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
index cce3e36..561867f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
@@ -25,6 +25,7 @@
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.temporarydisplay.TemporaryViewInfo
import com.android.systemui.util.mockito.any
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -40,7 +41,7 @@
private lateinit var appIconFromPackageName: Drawable
@Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var applicationInfo: ApplicationInfo
- @Mock private lateinit var logger: MediaTttLogger
+ @Mock private lateinit var logger: MediaTttLogger<TemporaryViewInfo>
@Before
fun setUp() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
index 4aa982e..07a3109 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
@@ -22,28 +22,32 @@
import android.view.ViewGroup
import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
+import com.android.systemui.dump.DumpManager
import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.view.ViewUtil
import com.android.systemui.util.wakelock.WakeLock
class FakeMediaTttChipControllerReceiver(
commandQueue: CommandQueue,
context: Context,
- logger: MediaTttLogger,
+ logger: MediaTttLogger<ChipReceiverInfo>,
windowManager: WindowManager,
mainExecutor: DelayableExecutor,
accessibilityManager: AccessibilityManager,
configurationController: ConfigurationController,
+ dumpManager: DumpManager,
powerManager: PowerManager,
mainHandler: Handler,
mediaTttFlags: MediaTttFlags,
uiEventLogger: MediaTttReceiverUiEventLogger,
viewUtil: ViewUtil,
wakeLockBuilder: WakeLock.Builder,
+ systemClock: SystemClock,
) :
MediaTttChipControllerReceiver(
commandQueue,
@@ -53,12 +57,14 @@
mainExecutor,
accessibilityManager,
configurationController,
+ dumpManager,
powerManager,
mainHandler,
mediaTttFlags,
uiEventLogger,
viewUtil,
wakeLockBuilder,
+ systemClock,
) {
override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) {
// Just bypass the animation in tests
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 23f7cdb..03ba3d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -34,6 +34,7 @@
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.statusbar.CommandQueue
@@ -67,12 +68,14 @@
@Mock
private lateinit var applicationInfo: ApplicationInfo
@Mock
- private lateinit var logger: MediaTttLogger
+ private lateinit var logger: MediaTttLogger<ChipReceiverInfo>
@Mock
private lateinit var accessibilityManager: AccessibilityManager
@Mock
private lateinit var configurationController: ConfigurationController
@Mock
+ private lateinit var dumpManager: DumpManager
+ @Mock
private lateinit var mediaTttFlags: MediaTttFlags
@Mock
private lateinit var powerManager: PowerManager
@@ -122,12 +125,14 @@
fakeExecutor,
accessibilityManager,
configurationController,
+ dumpManager,
powerManager,
Handler.getMain(),
mediaTttFlags,
receiverUiEventLogger,
viewUtil,
fakeWakeLockBuilder,
+ fakeClock,
)
controllerReceiver.start()
@@ -149,12 +154,14 @@
FakeExecutor(FakeSystemClock()),
accessibilityManager,
configurationController,
+ dumpManager,
powerManager,
Handler.getMain(),
mediaTttFlags,
receiverUiEventLogger,
viewUtil,
fakeWakeLockBuilder,
+ fakeClock,
)
controllerReceiver.start()
@@ -193,6 +200,36 @@
}
@Test
+ fun commandQueueCallback_transferToReceiverSucceeded_noChipShown() {
+ commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ routeInfo,
+ null,
+ null
+ )
+
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_SUCCEEDED.id
+ )
+ }
+
+ @Test
+ fun commandQueueCallback_transferToReceiverFailed_noChipShown() {
+ commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_FAILED,
+ routeInfo,
+ null,
+ null
+ )
+
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_FAILED.id
+ )
+ }
+
+ @Test
fun commandQueueCallback_closeThenFar_chipShownThenHidden() {
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
@@ -214,6 +251,48 @@
}
@Test
+ fun commandQueueCallback_closeThenSucceeded_chipShownThenHidden() {
+ commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
+ routeInfo,
+ null,
+ null
+ )
+
+ commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ routeInfo,
+ null,
+ null
+ )
+
+ val viewCaptor = ArgumentCaptor.forClass(View::class.java)
+ verify(windowManager).addView(viewCaptor.capture(), any())
+ verify(windowManager).removeView(viewCaptor.value)
+ }
+
+ @Test
+ fun commandQueueCallback_closeThenFailed_chipShownThenHidden() {
+ commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
+ routeInfo,
+ null,
+ null
+ )
+
+ commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_FAILED,
+ routeInfo,
+ null,
+ null
+ )
+
+ val viewCaptor = ArgumentCaptor.forClass(View::class.java)
+ verify(windowManager).addView(viewCaptor.capture(), any())
+ verify(windowManager).removeView(viewCaptor.value)
+ }
+
+ @Test
fun commandQueueCallback_closeThenFar_wakeLockAcquiredThenReleased() {
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
index 311740e..4cc12c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
@@ -38,6 +38,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.common.shared.model.Text.Companion.loadText
+import com.android.systemui.dump.DumpManager
import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.plugins.FalsingManager
@@ -45,6 +46,7 @@
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
+import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo
import com.android.systemui.temporarydisplay.chipbar.ChipbarLogger
import com.android.systemui.temporarydisplay.chipbar.FakeChipbarCoordinator
import com.android.systemui.util.concurrency.FakeExecutor
@@ -80,10 +82,11 @@
@Mock private lateinit var applicationInfo: ApplicationInfo
@Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var configurationController: ConfigurationController
+ @Mock private lateinit var dumpManager: DumpManager
@Mock private lateinit var falsingManager: FalsingManager
@Mock private lateinit var falsingCollector: FalsingCollector
@Mock private lateinit var chipbarLogger: ChipbarLogger
- @Mock private lateinit var logger: MediaTttLogger
+ @Mock private lateinit var logger: MediaTttLogger<ChipbarInfo>
@Mock private lateinit var mediaTttFlags: MediaTttFlags
@Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var powerManager: PowerManager
@@ -136,12 +139,14 @@
fakeExecutor,
accessibilityManager,
configurationController,
+ dumpManager,
powerManager,
falsingManager,
falsingCollector,
viewUtil,
vibratorHelper,
fakeWakeLockBuilder,
+ fakeClock,
)
chipbarCoordinator.start()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS
new file mode 100644
index 0000000..7ccb316
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 1254381
+azappone@google.com
+achalke@google.com
+juliacr@google.com
+madym@google.com
+mgalhardo@google.com
+petrcermak@google.com
+vanjan@google.com
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index caf8321..5058373 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -226,7 +226,8 @@
+ " " + mockTileViewString + "\n"
+ " media bounds: null\n"
+ " horizontal layout: false\n"
- + " last orientation: 0\n";
+ + " last orientation: 0\n"
+ + " mShouldUseSplitNotificationShade: false\n";
assertEquals(expected, w.getBuffer().toString());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index 5e082f6..6cf642c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -135,10 +135,10 @@
fun configurationChange_onlySplitShadeConfigChanges_tileAreRedistributed() {
testableResources.addOverride(R.bool.config_use_split_notification_shade, false)
controller.mOnConfigurationChangedListener.onConfigurationChange(configuration)
- verify(pagedTileLayout, never()).forceTilesRedistribution()
+ verify(pagedTileLayout, never()).forceTilesRedistribution(any())
testableResources.addOverride(R.bool.config_use_split_notification_shade, true)
controller.mOnConfigurationChangedListener.onConfigurationChange(configuration)
- verify(pagedTileLayout).forceTilesRedistribution()
+ verify(pagedTileLayout).forceTilesRedistribution("Split shade state changed")
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
index 7c930b1..d52b296 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
@@ -27,6 +27,7 @@
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSIconViewImpl
import com.android.systemui.qs.tileimpl.QSTileViewImpl
import com.google.common.truth.Truth.assertThat
@@ -34,6 +35,7 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -42,6 +44,9 @@
@RunWithLooper
@SmallTest
class QSPanelTest : SysuiTestCase() {
+
+ @Mock private lateinit var qsLogger: QSLogger
+
private lateinit var testableLooper: TestableLooper
private lateinit var qsPanel: QSPanel
@@ -57,7 +62,7 @@
qsPanel = QSPanel(context, null)
qsPanel.mUsingMediaPlayer = true
- qsPanel.initialize()
+ qsPanel.initialize(qsLogger)
// QSPanel inflates a footer inside of it, mocking it here
footer = LinearLayout(context).apply { id = R.id.qs_footer }
qsPanel.addView(footer, MATCH_PARENT, 100)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt
index a6a584d..3fba393 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt
@@ -7,10 +7,12 @@
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.logging.QSLogger
import com.google.common.truth.Truth
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
@@ -19,6 +21,8 @@
@SmallTest
class QuickQSPanelTest : SysuiTestCase() {
+ @Mock private lateinit var qsLogger: QSLogger
+
private lateinit var testableLooper: TestableLooper
private lateinit var quickQSPanel: QuickQSPanel
@@ -32,7 +36,7 @@
testableLooper.runWithLooper {
quickQSPanel = QuickQSPanel(mContext, null)
- quickQSPanel.initialize()
+ quickQSPanel.initialize(qsLogger)
quickQSPanel.onFinishInflate()
// Provides a parent with non-zero size for QSPanel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
index f3fcdbf..2bd068a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.external
+import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.pm.ApplicationInfo
@@ -30,8 +31,10 @@
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.IWindowManager
+import android.view.View
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.qs.QSTile
@@ -39,8 +42,11 @@
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.nullable
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
+import org.junit.Assert.assertThrows
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
@@ -236,6 +242,10 @@
`when`(tile.qsTile.icon.loadDrawable(any(Context::class.java)))
.thenReturn(mock(Drawable::class.java))
+ val pi = mock(PendingIntent::class.java)
+ `when`(pi.isActivity).thenReturn(true)
+ tile.qsTile.activityLaunchForClick = pi
+
tile.refreshState()
testableLooper.processAllMessages()
@@ -289,4 +299,52 @@
assertFalse(tile.isAvailable)
verify(tileHost).removeTile(tile.tileSpec)
}
+
+ @Test
+ fun testInvalidPendingIntentDoesNotStartActivity() {
+ val pi = mock(PendingIntent::class.java)
+ `when`(pi.isActivity).thenReturn(false)
+ val tile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
+
+ assertThrows(IllegalArgumentException::class.java) {
+ tile.qsTile.activityLaunchForClick = pi
+ }
+
+ tile.handleClick(mock(View::class.java))
+ testableLooper.processAllMessages()
+
+ verify(activityStarter, never())
+ .startPendingIntentDismissingKeyguard(
+ any(), any(), any(ActivityLaunchAnimator.Controller::class.java))
+ }
+
+ @Test
+ fun testValidPendingIntentWithNoClickDoesNotStartActivity() {
+ val pi = mock(PendingIntent::class.java)
+ `when`(pi.isActivity).thenReturn(true)
+ val tile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
+ tile.qsTile.activityLaunchForClick = pi
+
+ testableLooper.processAllMessages()
+
+ verify(activityStarter, never())
+ .startPendingIntentDismissingKeyguard(
+ any(), any(), any(ActivityLaunchAnimator.Controller::class.java))
+ }
+
+ @Test
+ fun testValidPendingIntentStartsActivity() {
+ val pi = mock(PendingIntent::class.java)
+ `when`(pi.isActivity).thenReturn(true)
+ val tile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
+ tile.qsTile.activityLaunchForClick = pi
+
+ tile.handleClick(mock(View::class.java))
+
+ testableLooper.processAllMessages()
+
+ verify(activityStarter)
+ .startPendingIntentDismissingKeyguard(
+ eq(pi), nullable(), nullable<ActivityLaunchAnimator.Controller>())
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 25c95ef..172c87f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Handler;
@@ -58,6 +59,7 @@
import com.android.systemui.util.settings.SecureSettings;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -245,6 +247,32 @@
verify(manager.getTileService()).onStartListening();
}
+ @Test
+ public void testValidCustomTileStartsActivity() {
+ CustomTile tile = mock(CustomTile.class);
+ PendingIntent pi = mock(PendingIntent.class);
+ ComponentName componentName = mock(ComponentName.class);
+ when(tile.getComponent()).thenReturn(componentName);
+ when(componentName.getPackageName()).thenReturn(this.getContext().getPackageName());
+
+ mTileService.startActivity(tile, pi);
+
+ verify(tile).startActivityAndCollapse(pi);
+ }
+
+ @Test
+ public void testInvalidCustomTileDoesNotStartActivity() {
+ CustomTile tile = mock(CustomTile.class);
+ PendingIntent pi = mock(PendingIntent.class);
+ ComponentName componentName = mock(ComponentName.class);
+ when(tile.getComponent()).thenReturn(componentName);
+ when(componentName.getPackageName()).thenReturn("invalid.package.name");
+
+ Assert.assertThrows(SecurityException.class, () -> mTileService.startActivity(tile, pi));
+
+ verify(tile, never()).startActivityAndCollapse(pi);
+ }
+
private class TestTileServices extends TileServices {
TestTileServices(QSTileHost host, Provider<Handler> handlerProvider,
BroadcastDispatcher broadcastDispatcher, UserTracker userTracker,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt
index 01411c9..0b9fbd9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt
@@ -84,7 +84,7 @@
ContentDescription.Resource(R.string.accessibility_quick_settings_settings)
)
)
- assertThat(settings.background).isEqualTo(R.drawable.qs_footer_action_circle)
+ assertThat(settings.backgroundColor).isEqualTo(R.attr.offStateColor)
assertThat(settings.iconTint).isNull()
}
@@ -105,7 +105,7 @@
ContentDescription.Resource(R.string.accessibility_quick_settings_power_menu)
)
)
- assertThat(power.background).isEqualTo(R.drawable.qs_footer_action_circle_color)
+ assertThat(power.backgroundColor).isEqualTo(com.android.internal.R.attr.colorAccent)
assertThat(power.iconTint)
.isEqualTo(
Utils.getColorAttrDefaultColor(
@@ -170,7 +170,7 @@
assertThat(userSwitcher).isNotNull()
assertThat(userSwitcher!!.icon)
.isEqualTo(Icon.Loaded(picture, ContentDescription.Loaded("Signed in as foo")))
- assertThat(userSwitcher.background).isEqualTo(R.drawable.qs_footer_action_circle)
+ assertThat(userSwitcher.backgroundColor).isEqualTo(R.attr.offStateColor)
// Change the current user name.
userSwitcherControllerWrapper.currentUserName = "bar"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 3512749..01f13e66 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -219,6 +219,7 @@
@Mock private KeyguardStateController mKeyguardStateController;
@Mock private DozeLog mDozeLog;
@Mock private ShadeLogger mShadeLog;
+ @Mock private ShadeHeightLogger mShadeHeightLogger;
@Mock private CommandQueue mCommandQueue;
@Mock private VibratorHelper mVibratorHelper;
@Mock private LatencyTracker mLatencyTracker;
@@ -455,6 +456,7 @@
mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor,
mMetricsLogger,
mShadeLog,
+ mShadeHeightLogger,
mConfigurationController,
() -> flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager,
mConversationNotificationManager, mMediaHierarchyManager,
@@ -1681,6 +1683,42 @@
assertThat(mNotificationPanelViewController.isFullyExpanded()).isTrue();
}
+ @Test
+ public void shadeExpanded_inShadeState() {
+ mStatusBarStateController.setState(SHADE);
+
+ mNotificationPanelViewController.setExpandedHeight(0);
+ assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isFalse();
+
+ int transitionDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance();
+ mNotificationPanelViewController.setExpandedHeight(transitionDistance);
+ assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue();
+ }
+
+ @Test
+ public void shadeExpanded_onKeyguard() {
+ mStatusBarStateController.setState(KEYGUARD);
+
+ int transitionDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance();
+ mNotificationPanelViewController.setExpandedHeight(transitionDistance);
+ assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isFalse();
+
+ // set maxQsExpansion in NPVC
+ int maxQsExpansion = 123;
+ mNotificationPanelViewController.setQs(mQs);
+ when(mQs.getDesiredHeight()).thenReturn(maxQsExpansion);
+ triggerLayoutChange();
+
+ mNotificationPanelViewController.setQsExpansionHeight(maxQsExpansion);
+ assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue();
+ }
+
+ @Test
+ public void shadeExpanded_onShadeLocked() {
+ mStatusBarStateController.setState(SHADE_LOCKED);
+ assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue();
+ }
+
private static MotionEvent createMotionEvent(int x, int y, int action) {
return MotionEvent.obtain(
/* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index c280ec8..8d96932 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -1042,7 +1042,7 @@
// GIVEN a trust granted message but trust isn't granted
final String trustGrantedMsg = "testing trust granted message";
mController.getKeyguardCallback().onTrustGrantedForCurrentUser(
- false, new TrustGrantFlags(0), trustGrantedMsg);
+ false, false, new TrustGrantFlags(0), trustGrantedMsg);
verifyHideIndication(INDICATION_TYPE_TRUST);
@@ -1067,7 +1067,7 @@
// WHEN the showTrustGranted method is called
final String trustGrantedMsg = "testing trust granted message";
mController.getKeyguardCallback().onTrustGrantedForCurrentUser(
- false, new TrustGrantFlags(0), trustGrantedMsg);
+ false, false, new TrustGrantFlags(0), trustGrantedMsg);
// THEN verify the trust granted message shows
verifyIndicationMessage(
@@ -1085,7 +1085,7 @@
// WHEN the showTrustGranted method is called with a null message
mController.getKeyguardCallback().onTrustGrantedForCurrentUser(
- false, new TrustGrantFlags(0), null);
+ false, false, new TrustGrantFlags(0), null);
// THEN verify the default trust granted message shows
verifyIndicationMessage(
@@ -1103,7 +1103,7 @@
// WHEN the showTrustGranted method is called with an EMPTY string
mController.getKeyguardCallback().onTrustGrantedForCurrentUser(
- false, new TrustGrantFlags(0), "");
+ false, false, new TrustGrantFlags(0), "");
// THEN verify NO trust message is shown
verifyNoMessage(INDICATION_TYPE_TRUST);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
index 5f19fac..be6b1dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
@@ -18,6 +18,8 @@
package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification
+import android.os.UserHandle
+import android.provider.Settings
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -29,6 +31,7 @@
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider
@@ -38,6 +41,7 @@
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -47,6 +51,8 @@
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.same
+import org.mockito.Mockito.anyString
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.verify
import java.util.function.Consumer
@@ -176,6 +182,42 @@
}
@Test
+ fun unseenFilterInvalidatesWhenSettingChanges() {
+ whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
+
+ // GIVEN: Keyguard is not showing
+ keyguardRepository.setKeyguardShowing(false)
+ runKeyguardCoordinatorTest {
+ // GIVEN: A notification is present
+ val fakeEntry = NotificationEntryBuilder().build()
+ collectionListener.onEntryAdded(fakeEntry)
+
+ // GIVEN: The setting for filtering unseen notifications is disabled
+ showOnlyUnseenNotifsOnKeyguardSetting = false
+
+ // GIVEN: The pipeline has registered the unseen filter for invalidation
+ val invalidationListener: Pluggable.PluggableListener<NotifFilter> = mock()
+ unseenFilter.setInvalidationListener(invalidationListener)
+
+ // WHEN: The keyguard is now showing
+ keyguardRepository.setKeyguardShowing(true)
+ testScheduler.runCurrent()
+
+ // THEN: The notification is not filtered out
+ assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isFalse()
+
+ // WHEN: The secure setting is changed
+ showOnlyUnseenNotifsOnKeyguardSetting = true
+
+ // THEN: The pipeline is invalidated
+ verify(invalidationListener).onPluggableInvalidated(same(unseenFilter), anyString())
+
+ // THEN: The notification is recognized as "seen" and is filtered out.
+ assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isTrue()
+ }
+ }
+
+ @Test
fun unseenFilterAllowsNewNotif() {
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
@@ -276,22 +318,32 @@
private fun runKeyguardCoordinatorTest(
testBlock: suspend KeyguardCoordinatorTestScope.() -> Unit
) {
- val testScope = TestScope(UnconfinedTestDispatcher())
+ val testDispatcher = UnconfinedTestDispatcher()
+ val testScope = TestScope(testDispatcher)
+ val fakeSettings = FakeSettings().apply {
+ putBool(Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, true)
+ }
val seenNotificationsProvider = SeenNotificationsProviderImpl()
val keyguardCoordinator =
KeyguardCoordinator(
+ testDispatcher,
keyguardNotifVisibilityProvider,
keyguardRepository,
notifPipelineFlags,
testScope.backgroundScope,
sectionHeaderVisibilityProvider,
+ fakeSettings,
seenNotificationsProvider,
statusBarStateController,
)
keyguardCoordinator.attach(notifPipeline)
testScope.runTest(dispatchTimeoutMs = 1.seconds.inWholeMilliseconds) {
- KeyguardCoordinatorTestScope(keyguardCoordinator, testScope, seenNotificationsProvider)
- .testBlock()
+ KeyguardCoordinatorTestScope(
+ keyguardCoordinator,
+ testScope,
+ seenNotificationsProvider,
+ fakeSettings,
+ ).testBlock()
}
}
@@ -299,6 +351,7 @@
private val keyguardCoordinator: KeyguardCoordinator,
private val scope: TestScope,
val seenNotificationsProvider: SeenNotificationsProvider,
+ private val fakeSettings: FakeSettings,
) : CoroutineScope by scope {
val testScheduler: TestCoroutineScheduler
get() = scope.testScheduler
@@ -316,5 +369,19 @@
val collectionListener: NotifCollectionListener by lazy {
withArgCaptor { verify(notifPipeline).addCollectionListener(capture()) }
}
+
+ var showOnlyUnseenNotifsOnKeyguardSetting: Boolean
+ get() =
+ fakeSettings.getBoolForUser(
+ Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
+ UserHandle.USER_CURRENT,
+ )
+ set(value) {
+ fakeSettings.putBoolForUser(
+ Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
+ value,
+ UserHandle.USER_CURRENT,
+ )
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/fsi/FsiChromeRepoTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/fsi/FsiChromeRepoTest.kt
new file mode 100644
index 0000000..a6a9e51
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/fsi/FsiChromeRepoTest.kt
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.fsi
+
+import android.R
+import android.app.Notification
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.graphics.drawable.Drawable
+import android.os.UserHandle
+import android.service.dreams.IDreamManager
+import android.service.notification.StatusBarNotification
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.LaunchFullScreenIntentProvider
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import java.util.concurrent.Executor
+import junit.framework.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+class FsiChromeRepoTest : SysuiTestCase() {
+
+ @Mock lateinit var centralSurfaces: CentralSurfaces
+ @Mock lateinit var fsiChromeRepo: FsiChromeRepo
+ @Mock lateinit var packageManager: PackageManager
+
+ var keyguardRepo = FakeKeyguardRepository()
+ @Mock private lateinit var applicationInfo: ApplicationInfo
+
+ @Mock lateinit var launchFullScreenIntentProvider: LaunchFullScreenIntentProvider
+ var featureFlags = FakeFeatureFlags()
+ @Mock lateinit var dreamManager: IDreamManager
+
+ // Execute all foreground & background requests immediately
+ private val uiBgExecutor = Executor { r -> r.run() }
+
+ private val appName: String = "appName"
+ private val appIcon: Drawable = context.getDrawable(com.android.systemui.R.drawable.ic_android)
+ private val fsi: PendingIntent = Mockito.mock(PendingIntent::class.java)
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ // Set up package manager mocks
+ whenever(packageManager.getApplicationIcon(anyString())).thenReturn(appIcon)
+ whenever(packageManager.getApplicationIcon(any(ApplicationInfo::class.java)))
+ .thenReturn(appIcon)
+ whenever(packageManager.getApplicationLabel(any())).thenReturn(appName)
+ mContext.setMockPackageManager(packageManager)
+
+ fsiChromeRepo =
+ FsiChromeRepo(
+ mContext,
+ packageManager,
+ keyguardRepo,
+ launchFullScreenIntentProvider,
+ featureFlags,
+ uiBgExecutor,
+ dreamManager,
+ centralSurfaces
+ )
+ }
+
+ private fun createFsiEntry(fsi: PendingIntent): NotificationEntry {
+ val nb =
+ Notification.Builder(mContext, "a")
+ .setContentTitle("foo")
+ .setSmallIcon(R.drawable.sym_def_app_icon)
+ .setFullScreenIntent(fsi, /* highPriority= */ true)
+
+ val sbn =
+ StatusBarNotification(
+ "pkg",
+ "opPkg",
+ /* id= */ 0,
+ "tag" + System.currentTimeMillis(),
+ /* uid= */ 0,
+ /* initialPid */ 0,
+ nb.build(),
+ UserHandle(0),
+ /* overrideGroupKey= */ null,
+ /* postTime= */ 0
+ )
+
+ val entry = Mockito.mock(NotificationEntry::class.java)
+ whenever(entry.importance).thenReturn(NotificationManager.IMPORTANCE_HIGH)
+ whenever(entry.sbn).thenReturn(sbn)
+ return entry
+ }
+
+ @Test
+ fun testLaunchFullscreenIntent_flagNotEnabled_noLaunch() {
+ // Setup
+ featureFlags.set(Flags.FSI_CHROME, false)
+
+ // Test
+ val entry = createFsiEntry(fsi)
+ fsiChromeRepo.launchFullscreenIntent(entry)
+
+ // Verify
+ Mockito.verify(centralSurfaces, never()).wakeUpForFullScreenIntent()
+ }
+
+ @Test
+ fun testLaunchFullscreenIntent_notOnKeyguard_noLaunch() {
+ // Setup
+ featureFlags.set(Flags.FSI_CHROME, true)
+ keyguardRepo.setKeyguardShowing(false)
+
+ // Test
+ val entry = createFsiEntry(fsi)
+ fsiChromeRepo.launchFullscreenIntent(entry)
+
+ // Verify
+ Mockito.verify(centralSurfaces, never()).wakeUpForFullScreenIntent()
+ }
+
+ @Test
+ fun testLaunchFullscreenIntent_stopsScreensaver() {
+ // Setup
+ featureFlags.set(Flags.FSI_CHROME, true)
+ keyguardRepo.setKeyguardShowing(true)
+
+ // Test
+ val entry = createFsiEntry(fsi)
+ fsiChromeRepo.launchFullscreenIntent(entry)
+
+ // Verify
+ Mockito.verify(dreamManager, times(1)).awaken()
+ }
+
+ @Test
+ fun testLaunchFullscreenIntent_updatesFsiInfoFlow() {
+ // Setup
+ featureFlags.set(Flags.FSI_CHROME, true)
+ keyguardRepo.setKeyguardShowing(true)
+
+ // Test
+ val entry = createFsiEntry(fsi)
+ fsiChromeRepo.launchFullscreenIntent(entry)
+
+ // Verify
+ val expectedFsiInfo = FsiChromeRepo.FSIInfo(appName, appIcon, fsi)
+ assertEquals(expectedFsiInfo, fsiChromeRepo.infoFlow.value)
+ }
+
+ @Test
+ fun testLaunchFullscreenIntent_notifyFsiLaunched() {
+ // Setup
+ featureFlags.set(Flags.FSI_CHROME, true)
+ keyguardRepo.setKeyguardShowing(true)
+
+ // Test
+ val entry = createFsiEntry(fsi)
+ fsiChromeRepo.launchFullscreenIntent(entry)
+
+ // Verify
+ Mockito.verify(entry, times(1)).notifyFullScreenIntentLaunched()
+ }
+
+ @Test
+ fun testLaunchFullscreenIntent_wakesUpDevice() {
+ // Setup
+ featureFlags.set(Flags.FSI_CHROME, true)
+ keyguardRepo.setKeyguardShowing(true)
+
+ // Test
+ val entry = createFsiEntry(fsi)
+ fsiChromeRepo.launchFullscreenIntent(entry)
+
+ // Verify
+ Mockito.verify(centralSurfaces, times(1)).wakeUpForFullScreenIntent()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/fsi/FsiChromeViewModelFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/fsi/FsiChromeViewModelFactoryTest.kt
new file mode 100644
index 0000000..5cee9e3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/fsi/FsiChromeViewModelFactoryTest.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.fsi
+
+import android.app.PendingIntent
+import android.graphics.drawable.Drawable
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.time.FakeSystemClock
+import com.android.wm.shell.TaskView
+import com.android.wm.shell.TaskViewFactory
+import com.google.common.truth.Truth.assertThat
+import java.util.Optional
+import java.util.function.Consumer
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+class FsiChromeViewModelFactoryTest : SysuiTestCase() {
+ @Mock private lateinit var taskViewFactoryOptional: Optional<TaskViewFactory>
+ @Mock private lateinit var taskViewFactory: TaskViewFactory
+ @Mock lateinit var taskView: TaskView
+
+ @Main var mainExecutor = FakeExecutor(FakeSystemClock())
+ lateinit var viewModelFactory: FsiChromeViewModelFactory
+
+ private val fakeInfoFlow = MutableStateFlow<FsiChromeRepo.FSIInfo?>(null)
+ private var fsiChromeRepo: FsiChromeRepo =
+ mock<FsiChromeRepo>().apply { whenever(infoFlow).thenReturn(fakeInfoFlow) }
+
+ private val appName = "appName"
+ private val appIcon: Drawable = context.getDrawable(com.android.systemui.R.drawable.ic_android)
+ private val fsi: PendingIntent = Mockito.mock(PendingIntent::class.java)
+ private val fsiInfo = FsiChromeRepo.FSIInfo(appName, appIcon, fsi)
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ whenever(taskViewFactoryOptional.get()).thenReturn(taskViewFactory)
+
+ viewModelFactory =
+ FsiChromeViewModelFactory(fsiChromeRepo, taskViewFactoryOptional, context, mainExecutor)
+ }
+
+ @Test
+ fun testViewModelFlow_update_createsTaskView() {
+ runTest {
+ val latestViewModel =
+ viewModelFactory.viewModelFlow
+ .onStart { FsiDebug.log("viewModelFactory.viewModelFlow.onStart") }
+ .stateIn(
+ backgroundScope, // stateIn runs forever, don't count it as test coroutine
+ SharingStarted.Eagerly,
+ null
+ )
+ runCurrent() // Drain queued backgroundScope operations
+
+ // Test: emit the fake FSIInfo
+ fakeInfoFlow.emit(fsiInfo)
+ runCurrent()
+
+ val taskViewFactoryCallback: Consumer<TaskView> = withArgCaptor {
+ verify(taskViewFactory).create(any(), any(), capture())
+ }
+ taskViewFactoryCallback.accept(taskView) // this will call k.resume
+ runCurrent()
+
+ // Verify that the factory has produced a new ViewModel
+ // containing the relevant data from FsiInfo
+ val expectedViewModel =
+ FsiChromeViewModel(appName, appIcon, taskView, fsi, fsiChromeRepo)
+
+ assertThat(latestViewModel.value).isEqualTo(expectedViewModel)
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
new file mode 100644
index 0000000..33b94e3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.logging
+
+import android.app.Notification
+import android.app.StatsManager
+import android.graphics.Bitmap
+import android.graphics.drawable.Icon
+import android.testing.AndroidTestingRunner
+import android.util.StatsEvent
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.shared.system.SysUiStatsLog
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class NotificationMemoryLoggerTest : SysuiTestCase() {
+
+ private val bgExecutor = FakeExecutor(FakeSystemClock())
+ private val immediate = Dispatchers.Main.immediate
+
+ @Mock private lateinit var statsManager: StatsManager
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ }
+
+ @Test
+ fun onInit_registersCallback() {
+ val logger = createLoggerWithNotifications(listOf())
+ logger.init()
+ verify(statsManager)
+ .setPullAtomCallback(SysUiStatsLog.NOTIFICATION_MEMORY_USE, null, bgExecutor, logger)
+ }
+
+ @Test
+ fun onPullAtom_wrongAtomId_returnsSkip() {
+ val logger = createLoggerWithNotifications(listOf())
+ val data: MutableList<StatsEvent> = mutableListOf()
+ assertThat(logger.onPullAtom(111, data)).isEqualTo(StatsManager.PULL_SKIP)
+ assertThat(data).isEmpty()
+ }
+
+ @Test
+ fun onPullAtom_emptyNotifications_returnsZeros() {
+ val logger = createLoggerWithNotifications(listOf())
+ val data: MutableList<StatsEvent> = mutableListOf()
+ assertThat(logger.onPullAtom(SysUiStatsLog.NOTIFICATION_MEMORY_USE, data))
+ .isEqualTo(StatsManager.PULL_SUCCESS)
+ assertThat(data).isEmpty()
+ }
+
+ @Test
+ fun onPullAtom_notificationPassed_populatesData() {
+ val icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888))
+ val notification =
+ Notification.Builder(context).setSmallIcon(icon).setContentTitle("title").build()
+ val logger = createLoggerWithNotifications(listOf(notification))
+ val data: MutableList<StatsEvent> = mutableListOf()
+
+ assertThat(logger.onPullAtom(SysUiStatsLog.NOTIFICATION_MEMORY_USE, data))
+ .isEqualTo(StatsManager.PULL_SUCCESS)
+ assertThat(data).hasSize(1)
+ }
+
+ @Test
+ fun onPullAtom_multipleNotificationsPassed_populatesData() {
+ val icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888))
+ val notification =
+ Notification.Builder(context).setSmallIcon(icon).setContentTitle("title").build()
+ val iconTwo = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888))
+
+ val notificationTwo =
+ Notification.Builder(context)
+ .setStyle(Notification.BigTextStyle().bigText("text"))
+ .setSmallIcon(iconTwo)
+ .setContentTitle("titleTwo")
+ .build()
+ val logger = createLoggerWithNotifications(listOf(notification, notificationTwo))
+ val data: MutableList<StatsEvent> = mutableListOf()
+
+ assertThat(logger.onPullAtom(SysUiStatsLog.NOTIFICATION_MEMORY_USE, data))
+ .isEqualTo(StatsManager.PULL_SUCCESS)
+ assertThat(data).hasSize(2)
+ }
+
+ private fun createLoggerWithNotifications(
+ notifications: List<Notification>
+ ): NotificationMemoryLogger {
+ val pipeline: NotifPipeline = mock()
+ val notifications =
+ notifications.map { notification ->
+ NotificationEntryBuilder().setTag("test").setNotification(notification).build()
+ }
+ whenever(pipeline.allNotifs).thenReturn(notifications)
+ return NotificationMemoryLogger(pipeline, statsManager, immediate, bgExecutor)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt
index f69839b..072a497 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt
@@ -23,6 +23,7 @@
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Icon
+import android.stats.sysui.NotificationEnums
import android.testing.AndroidTestingRunner
import android.widget.RemoteViews
import androidx.test.filters.SmallTest
@@ -50,7 +51,27 @@
extras = 3316,
bigPicture = 0,
extender = 0,
- style = null,
+ style = NotificationEnums.STYLE_NONE,
+ styleIcon = 0,
+ hasCustomView = false,
+ )
+ }
+
+ @Test
+ fun currentNotificationMemoryUse_rankerGroupNotification() {
+ val notification = createBasicNotification().build()
+ val memoryUse =
+ NotificationMemoryMeter.notificationMemoryUse(
+ createNotificationEntry(createBasicNotification().setGroup("ranker_group").build())
+ )
+ assertNotificationObjectSizes(
+ memoryUse,
+ smallIcon = notification.smallIcon.bitmap.allocationByteCount,
+ largeIcon = notification.getLargeIcon().bitmap.allocationByteCount,
+ extras = 3316,
+ bigPicture = 0,
+ extender = 0,
+ style = NotificationEnums.STYLE_RANKER_GROUP,
styleIcon = 0,
hasCustomView = false,
)
@@ -69,7 +90,7 @@
extras = 3316,
bigPicture = 0,
extender = 0,
- style = null,
+ style = NotificationEnums.STYLE_NONE,
styleIcon = 0,
hasCustomView = false,
)
@@ -92,7 +113,7 @@
extras = 3384,
bigPicture = 0,
extender = 0,
- style = null,
+ style = NotificationEnums.STYLE_NONE,
styleIcon = 0,
hasCustomView = true,
)
@@ -112,7 +133,7 @@
extras = 3212,
bigPicture = 0,
extender = 0,
- style = null,
+ style = NotificationEnums.STYLE_NONE,
styleIcon = 0,
hasCustomView = false,
)
@@ -141,7 +162,7 @@
extras = 4092,
bigPicture = bigPicture.bitmap.allocationByteCount,
extender = 0,
- style = "BigPictureStyle",
+ style = NotificationEnums.STYLE_BIG_PICTURE,
styleIcon = bigPictureIcon.bitmap.allocationByteCount,
hasCustomView = false,
)
@@ -167,7 +188,7 @@
extras = 4084,
bigPicture = 0,
extender = 0,
- style = "CallStyle",
+ style = NotificationEnums.STYLE_CALL,
styleIcon = personIcon.bitmap.allocationByteCount,
hasCustomView = false,
)
@@ -203,7 +224,7 @@
extras = 5024,
bigPicture = 0,
extender = 0,
- style = "MessagingStyle",
+ style = NotificationEnums.STYLE_MESSAGING,
styleIcon =
personIcon.bitmap.allocationByteCount +
historicPersonIcon.bitmap.allocationByteCount,
@@ -225,7 +246,7 @@
extras = 3612,
bigPicture = 0,
extender = 556656,
- style = null,
+ style = NotificationEnums.STYLE_NONE,
styleIcon = 0,
hasCustomView = false,
)
@@ -246,7 +267,7 @@
extras = 3820,
bigPicture = 0,
extender = 388 + wearBackground.allocationByteCount,
- style = null,
+ style = NotificationEnums.STYLE_NONE,
styleIcon = 0,
hasCustomView = false,
)
@@ -272,7 +293,7 @@
extras: Int,
bigPicture: Int,
extender: Int,
- style: String?,
+ style: Int,
styleIcon: Int,
hasCustomView: Boolean,
) {
@@ -282,11 +303,7 @@
assertThat(memoryUse.objectUsage.smallIcon).isEqualTo(smallIcon)
assertThat(memoryUse.objectUsage.largeIcon).isEqualTo(largeIcon)
assertThat(memoryUse.objectUsage.bigPicture).isEqualTo(bigPicture)
- if (style == null) {
- assertThat(memoryUse.objectUsage.style).isNull()
- } else {
- assertThat(memoryUse.objectUsage.style).isEqualTo(style)
- }
+ assertThat(memoryUse.objectUsage.style).isEqualTo(style)
assertThat(memoryUse.objectUsage.styleIcon).isEqualTo(styleIcon)
assertThat(memoryUse.objectUsage.hasCustomView).isEqualTo(hasCustomView)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt
index 3a16fb3..a0f5048 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt
@@ -8,6 +8,7 @@
import android.widget.RemoteViews
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder
import com.android.systemui.statusbar.notification.row.NotificationTestHelper
import com.android.systemui.tests.R
import com.google.common.truth.Truth.assertThat
@@ -39,16 +40,84 @@
fun testViewWalker_plainNotification() {
val row = testHelper.createRow()
val result = NotificationMemoryViewWalker.getViewUsage(row)
- assertThat(result).hasSize(5)
- assertThat(result).contains(NotificationViewUsage(ViewType.PUBLIC_VIEW, 0, 0, 0, 0, 0, 0))
- assertThat(result)
- .contains(NotificationViewUsage(ViewType.PRIVATE_HEADS_UP_VIEW, 0, 0, 0, 0, 0, 0))
+ assertThat(result).hasSize(3)
assertThat(result)
.contains(NotificationViewUsage(ViewType.PRIVATE_EXPANDED_VIEW, 0, 0, 0, 0, 0, 0))
assertThat(result)
.contains(NotificationViewUsage(ViewType.PRIVATE_CONTRACTED_VIEW, 0, 0, 0, 0, 0, 0))
+ assertThat(result).contains(NotificationViewUsage(ViewType.TOTAL, 0, 0, 0, 0, 0, 0))
+ }
+
+ @Test
+ fun testViewWalker_plainNotification_withPublicView() {
+ val icon = Icon.createWithBitmap(Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888))
+ val publicIcon = Icon.createWithBitmap(Bitmap.createBitmap(40, 40, Bitmap.Config.ARGB_8888))
+ testHelper.setDefaultInflationFlags(NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL)
+ val row =
+ testHelper.createRow(
+ Notification.Builder(mContext)
+ .setContentText("Test")
+ .setContentTitle("title")
+ .setSmallIcon(icon)
+ .setPublicVersion(
+ Notification.Builder(mContext)
+ .setContentText("Public Test")
+ .setContentTitle("title")
+ .setSmallIcon(publicIcon)
+ .build()
+ )
+ .build()
+ )
+ val result = NotificationMemoryViewWalker.getViewUsage(row)
+ assertThat(result).hasSize(4)
assertThat(result)
- .contains(NotificationViewUsage(ViewType.PRIVATE_HEADS_UP_VIEW, 0, 0, 0, 0, 0, 0))
+ .contains(
+ NotificationViewUsage(
+ ViewType.PRIVATE_EXPANDED_VIEW,
+ icon.bitmap.allocationByteCount,
+ 0,
+ 0,
+ 0,
+ 0,
+ icon.bitmap.allocationByteCount
+ )
+ )
+ assertThat(result)
+ .contains(
+ NotificationViewUsage(
+ ViewType.PRIVATE_CONTRACTED_VIEW,
+ icon.bitmap.allocationByteCount,
+ 0,
+ 0,
+ 0,
+ 0,
+ icon.bitmap.allocationByteCount
+ )
+ )
+ assertThat(result)
+ .contains(
+ NotificationViewUsage(
+ ViewType.PUBLIC_VIEW,
+ publicIcon.bitmap.allocationByteCount,
+ 0,
+ 0,
+ 0,
+ 0,
+ publicIcon.bitmap.allocationByteCount
+ )
+ )
+ assertThat(result)
+ .contains(
+ NotificationViewUsage(
+ ViewType.TOTAL,
+ icon.bitmap.allocationByteCount + publicIcon.bitmap.allocationByteCount,
+ 0,
+ 0,
+ 0,
+ 0,
+ icon.bitmap.allocationByteCount + publicIcon.bitmap.allocationByteCount
+ )
+ )
}
@Test
@@ -67,7 +136,7 @@
.build()
)
val result = NotificationMemoryViewWalker.getViewUsage(row)
- assertThat(result).hasSize(5)
+ assertThat(result).hasSize(3)
assertThat(result)
.contains(
NotificationViewUsage(
@@ -95,8 +164,20 @@
icon.bitmap.allocationByteCount + largeIcon.bitmap.allocationByteCount
)
)
- // Due to deduplication, this should all be 0.
- assertThat(result).contains(NotificationViewUsage(ViewType.PUBLIC_VIEW, 0, 0, 0, 0, 0, 0))
+ assertThat(result)
+ .contains(
+ NotificationViewUsage(
+ ViewType.TOTAL,
+ icon.bitmap.allocationByteCount,
+ largeIcon.bitmap.allocationByteCount,
+ 0,
+ bigPicture.allocationByteCount,
+ 0,
+ bigPicture.allocationByteCount +
+ icon.bitmap.allocationByteCount +
+ largeIcon.bitmap.allocationByteCount
+ )
+ )
}
@Test
@@ -117,7 +198,7 @@
.build()
)
val result = NotificationMemoryViewWalker.getViewUsage(row)
- assertThat(result).hasSize(5)
+ assertThat(result).hasSize(3)
assertThat(result)
.contains(
NotificationViewUsage(
@@ -142,7 +223,17 @@
bitmap.allocationByteCount + icon.bitmap.allocationByteCount
)
)
- // Due to deduplication, this should all be 0.
- assertThat(result).contains(NotificationViewUsage(ViewType.PUBLIC_VIEW, 0, 0, 0, 0, 0, 0))
+ assertThat(result)
+ .contains(
+ NotificationViewUsage(
+ ViewType.TOTAL,
+ icon.bitmap.allocationByteCount,
+ 0,
+ 0,
+ 0,
+ bitmap.allocationByteCount,
+ bitmap.allocationByteCount + icon.bitmap.allocationByteCount
+ )
+ )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
index 5f57695..3f61af0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
@@ -26,6 +26,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.FakeShadowView
import com.android.systemui.statusbar.notification.NotificationUtils
+import com.android.systemui.statusbar.notification.SourceType
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -83,4 +84,17 @@
mView.updateBackgroundColors()
assertThat(mView.currentBackgroundTint).isEqualTo(mNormalColor)
}
+
+ @Test
+ fun roundnessShouldBeTheSame_after_onDensityOrFontScaleChanged() {
+ val roundableState = mView.roundableState
+ assertThat(mView.topRoundness).isEqualTo(0f)
+ mView.requestTopRoundness(1f, SourceType.from(""))
+ assertThat(mView.topRoundness).isEqualTo(1f)
+
+ mView.onDensityOrFontScaleChanged()
+
+ assertThat(mView.topRoundness).isEqualTo(1f)
+ assertThat(mView.roundableState.hashCode()).isEqualTo(roundableState.hashCode())
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 07ea630..7622549 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -20,6 +20,7 @@
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.RUBBER_BAND_FACTOR_NORMAL;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -47,6 +48,7 @@
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.testing.TestableResources;
import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.View;
@@ -99,6 +101,7 @@
private NotificationStackScrollLayout mStackScroller; // Normally test this
private NotificationStackScrollLayout mStackScrollerInternal; // See explanation below
private AmbientState mAmbientState;
+ private TestableResources mTestableResources;
@Rule public MockitoRule mockito = MockitoJUnit.rule();
@Mock private CentralSurfaces mCentralSurfaces;
@@ -123,6 +126,7 @@
@UiThreadTest
public void setUp() throws Exception {
allowTestableLooperAsMainThread();
+ mTestableResources = mContext.getOrCreateTestableResources();
// Interact with real instance of AmbientState.
mAmbientState = spy(new AmbientState(
@@ -394,7 +398,7 @@
@Test
@UiThreadTest
public void testSetExpandedHeight_withSplitShade_doesntInterpolateStackHeight() {
- mContext.getOrCreateTestableResources()
+ mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ true);
final int[] expectedStackHeight = {0};
@@ -405,12 +409,12 @@
.isEqualTo(expectedStackHeight[0]);
});
- mContext.getOrCreateTestableResources()
+ mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ false);
expectedStackHeight[0] = 0;
mStackScroller.setExpandedHeight(100f);
- mContext.getOrCreateTestableResources()
+ mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ true);
expectedStackHeight[0] = 100;
mStackScroller.setExpandedHeight(100f);
@@ -781,6 +785,39 @@
assertEquals(mAmbientState.getScrollY(), 0);
}
+ @Test
+ public void testSplitShade_hasTopOverscroll() {
+ mTestableResources
+ .addOverride(R.bool.config_use_split_notification_shade, /* value= */ true);
+ mStackScroller.updateSplitNotificationShade();
+ mAmbientState.setExpansionFraction(1f);
+
+ int topOverscrollPixels = 100;
+ mStackScroller.setOverScrolledPixels(topOverscrollPixels, true, false);
+
+ float expectedTopOverscrollAmount = topOverscrollPixels * RUBBER_BAND_FACTOR_NORMAL;
+ assertEquals(expectedTopOverscrollAmount, mStackScroller.getCurrentOverScrollAmount(true));
+ assertEquals(expectedTopOverscrollAmount, mAmbientState.getStackY());
+ }
+
+ @Test
+ public void testNormalShade_hasNoTopOverscroll() {
+ mTestableResources
+ .addOverride(R.bool.config_use_split_notification_shade, /* value= */ false);
+ mStackScroller.updateSplitNotificationShade();
+ mAmbientState.setExpansionFraction(1f);
+
+ int topOverscrollPixels = 100;
+ mStackScroller.setOverScrolledPixels(topOverscrollPixels, true, false);
+
+ float expectedTopOverscrollAmount = topOverscrollPixels * RUBBER_BAND_FACTOR_NORMAL;
+ assertEquals(expectedTopOverscrollAmount, mStackScroller.getCurrentOverScrollAmount(true));
+ // When not in split shade mode, then the overscroll effect is handled in
+ // NotificationPanelViewController and not in NotificationStackScrollLayout. Therefore
+ // mAmbientState must have stackY set to 0
+ assertEquals(0f, mAmbientState.getStackY());
+ }
+
private void setBarStateForTest(int state) {
// Can't inject this through the listener or we end up on the actual implementation
// rather than the mock because the spy just coppied the anonymous inner /shruggie.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 4d9db8c..5832569 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -518,7 +518,7 @@
val childHunView = createHunViewMock(
isShadeOpen = true,
fullyVisible = false,
- headerVisibleAmount = 1f
+ headerVisibleAmount = 1f,
)
val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
algorithmState.visibleChildren.add(childHunView)
@@ -526,7 +526,6 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
- /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -546,7 +545,7 @@
val childHunView = createHunViewMock(
isShadeOpen = true,
fullyVisible = false,
- headerVisibleAmount = 1f
+ headerVisibleAmount = 1f,
)
// Use half of the HUN's height as overlap
childHunView.viewState.yTranslation = (childHunView.viewState.height + 1 shr 1).toFloat()
@@ -556,7 +555,6 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
- /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -580,7 +578,7 @@
val childHunView = createHunViewMock(
isShadeOpen = true,
fullyVisible = true,
- headerVisibleAmount = 1f
+ headerVisibleAmount = 1f,
)
// HUN doesn't overlap with QQS Panel
childHunView.viewState.yTranslation = ambientState.topPadding +
@@ -591,7 +589,6 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
- /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -611,7 +608,7 @@
val childHunView = createHunViewMock(
isShadeOpen = false,
fullyVisible = false,
- headerVisibleAmount = 0f
+ headerVisibleAmount = 0f,
)
childHunView.viewState.yTranslation = 0f
// Shade is closed, thus childHunView's headerVisibleAmount is 0
@@ -622,7 +619,6 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
- /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -642,7 +638,7 @@
val childHunView = createHunViewMock(
isShadeOpen = false,
fullyVisible = false,
- headerVisibleAmount = 0.5f
+ headerVisibleAmount = 0.5f,
)
childHunView.viewState.yTranslation = 0f
// Shade is being opened, thus childHunView's headerVisibleAmount is between 0 and 1
@@ -654,7 +650,6 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
- /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -669,7 +664,7 @@
private fun createHunViewMock(
isShadeOpen: Boolean,
fullyVisible: Boolean,
- headerVisibleAmount: Float
+ headerVisibleAmount: Float,
) =
mock<ExpandableNotificationRow>().apply {
val childViewStateMock = createHunChildViewState(isShadeOpen, fullyVisible)
@@ -680,7 +675,10 @@
}
- private fun createHunChildViewState(isShadeOpen: Boolean, fullyVisible: Boolean) =
+ private fun createHunChildViewState(
+ isShadeOpen: Boolean,
+ fullyVisible: Boolean,
+ ) =
ExpandableViewState().apply {
// Mock the HUN's height with ambientState.topPadding +
// ambientState.stackTranslation
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 521e518..ae60c73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -19,6 +19,9 @@
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.StatusBarState.SHADE;
+
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertFalse;
@@ -831,7 +834,7 @@
when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
when(mNotificationsController.getActiveNotificationsCount()).thenReturn(5);
when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(true);
- mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+ mCentralSurfaces.setBarStateForTest(SHADE);
try {
mCentralSurfaces.handleVisibleToUserChanged(true);
@@ -850,7 +853,7 @@
when(mNotificationsController.getActiveNotificationsCount()).thenReturn(5);
when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(false);
- mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+ mCentralSurfaces.setBarStateForTest(SHADE);
try {
mCentralSurfaces.handleVisibleToUserChanged(true);
@@ -991,7 +994,7 @@
public void testShowKeyguardImplementation_setsState() {
when(mLockscreenUserManager.getCurrentProfiles()).thenReturn(new SparseArray<>());
- mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+ mCentralSurfaces.setBarStateForTest(SHADE);
// By default, showKeyguardImpl sets state to KEYGUARD.
mCentralSurfaces.showKeyguardImpl();
@@ -1048,7 +1051,7 @@
public void collapseShade_callsanimateCollapseShade_whenExpanded() {
// GIVEN the shade is expanded
mCentralSurfaces.onShadeExpansionFullyChanged(true);
- mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+ mCentralSurfaces.setBarStateForTest(SHADE);
// WHEN collapseShade is called
mCentralSurfaces.collapseShade();
@@ -1061,7 +1064,7 @@
public void collapseShade_doesNotCallanimateCollapseShade_whenCollapsed() {
// GIVEN the shade is collapsed
mCentralSurfaces.onShadeExpansionFullyChanged(false);
- mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+ mCentralSurfaces.setBarStateForTest(SHADE);
// WHEN collapseShade is called
mCentralSurfaces.collapseShade();
@@ -1074,7 +1077,7 @@
public void collapseShadeForBugReport_callsanimateCollapseShade_whenFlagDisabled() {
// GIVEN the shade is expanded & flag enabled
mCentralSurfaces.onShadeExpansionFullyChanged(true);
- mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+ mCentralSurfaces.setBarStateForTest(SHADE);
mFeatureFlags.set(Flags.LEAVE_SHADE_OPEN_FOR_BUGREPORT, false);
// WHEN collapseShadeForBugreport is called
@@ -1088,7 +1091,7 @@
public void collapseShadeForBugReport_doesNotCallanimateCollapseShade_whenFlagEnabled() {
// GIVEN the shade is expanded & flag enabled
mCentralSurfaces.onShadeExpansionFullyChanged(true);
- mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+ mCentralSurfaces.setBarStateForTest(SHADE);
mFeatureFlags.set(Flags.LEAVE_SHADE_OPEN_FOR_BUGREPORT, true);
// WHEN collapseShadeForBugreport is called
@@ -1100,10 +1103,10 @@
@Test
public void deviceStateChange_unfolded_shadeOpen_setsLeaveOpenOnKeyguardHide() {
- when(mKeyguardStateController.isShowing()).thenReturn(false);
setFoldedStates(FOLD_STATE_FOLDED);
setGoToSleepStates(FOLD_STATE_FOLDED);
- when(mNotificationPanelViewController.isFullyExpanded()).thenReturn(true);
+ mCentralSurfaces.setBarStateForTest(SHADE);
+ when(mNotificationPanelViewController.isShadeFullyOpen()).thenReturn(true);
setDeviceState(FOLD_STATE_UNFOLDED);
@@ -1112,10 +1115,10 @@
@Test
public void deviceStateChange_unfolded_shadeOpen_onKeyguard_doesNotSetLeaveOpenOnKeyguardHide() {
- when(mKeyguardStateController.isShowing()).thenReturn(true);
setFoldedStates(FOLD_STATE_FOLDED);
setGoToSleepStates(FOLD_STATE_FOLDED);
- when(mNotificationPanelViewController.isFullyExpanded()).thenReturn(true);
+ mCentralSurfaces.setBarStateForTest(KEYGUARD);
+ when(mNotificationPanelViewController.isShadeFullyOpen()).thenReturn(true);
setDeviceState(FOLD_STATE_UNFOLDED);
@@ -1127,7 +1130,8 @@
public void deviceStateChange_unfolded_shadeClose_doesNotSetLeaveOpenOnKeyguardHide() {
setFoldedStates(FOLD_STATE_FOLDED);
setGoToSleepStates(FOLD_STATE_FOLDED);
- when(mNotificationPanelViewController.isFullyExpanded()).thenReturn(false);
+ mCentralSurfaces.setBarStateForTest(SHADE);
+ when(mNotificationPanelViewController.isShadeFullyOpen()).thenReturn(false);
setDeviceState(FOLD_STATE_UNFOLDED);
@@ -1161,12 +1165,12 @@
// it to remain visible.
when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(true);
setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
- verify(mStatusBarStateController, never()).setState(StatusBarState.SHADE);
+ verify(mStatusBarStateController, never()).setState(SHADE);
// Once the animation ends, verify that the keyguard is actually hidden.
when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false);
setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
- verify(mStatusBarStateController).setState(StatusBarState.SHADE);
+ verify(mStatusBarStateController).setState(SHADE);
}
@Test
@@ -1179,7 +1183,7 @@
// immediately hide the keyguard.
when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false);
setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
- verify(mStatusBarStateController).setState(StatusBarState.SHADE);
+ verify(mStatusBarStateController).setState(SHADE);
}
/**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index cae414a..19658e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -55,6 +55,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -220,7 +221,8 @@
mock(NotificationPanelViewController.class),
mActivityLaunchAnimator,
notificationAnimationProvider,
- mock(LaunchFullScreenIntentProvider.class)
+ mock(LaunchFullScreenIntentProvider.class),
+ mock(FeatureFlags.class)
);
// set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
index 5265ec6..7b9929d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
@@ -30,6 +30,8 @@
private val _isDefaultDataSubscription = MutableStateFlow(true)
override val isDefaultDataSubscription = _isDefaultDataSubscription
+ override val cdmaRoaming = MutableStateFlow(false)
+
fun setConnectionInfo(model: MobileConnectionModel) {
_connectionInfo.value = model
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
index d6af0e6..04d3cdd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
@@ -20,6 +20,7 @@
import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
import com.android.settingslib.SignalIcon
+import com.android.settingslib.mobile.MobileMappings
import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
@@ -68,6 +69,8 @@
private val _globalMobileDataSettingChangedEvent = MutableStateFlow(Unit)
override val globalMobileDataSettingChangedEvent = _globalMobileDataSettingChangedEvent
+ override val defaultDataSubRatConfig = MutableStateFlow(MobileMappings.Config())
+
private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING)
override val defaultMobileIconMapping = _defaultMobileIconMapping
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
index e943de2..b2423da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
@@ -95,6 +95,7 @@
inflateStrength = testCase.inflateStrength,
activity = testCase.activity,
carrierNetworkChange = testCase.carrierNetworkChange,
+ roaming = testCase.roaming,
)
fakeNetworkEventFlow.value = networkModel
@@ -116,6 +117,7 @@
assertThat(connectionInfo.dataActivityDirection).isEqualTo(model.activity)
assertThat(connectionInfo.carrierNetworkChangeActive)
.isEqualTo(model.carrierNetworkChange)
+ assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming)
// TODO(b/261029387): check these once we start handling them
assertThat(connectionInfo.isEmergencyOnly).isFalse()
@@ -138,6 +140,7 @@
val inflateStrength: Boolean,
@Annotation.DataActivityType val activity: Int,
val carrierNetworkChange: Boolean,
+ val roaming: Boolean,
) {
override fun toString(): String {
return "INPUT(level=$level, " +
@@ -146,7 +149,8 @@
"carrierId=$carrierId, " +
"inflateStrength=$inflateStrength, " +
"activity=$activity, " +
- "carrierNetworkChange=$carrierNetworkChange)"
+ "carrierNetworkChange=$carrierNetworkChange, " +
+ "roaming=$roaming)"
}
// Convenience for iterating test data and creating new cases
@@ -158,6 +162,7 @@
inflateStrength: Boolean? = null,
@Annotation.DataActivityType activity: Int? = null,
carrierNetworkChange: Boolean? = null,
+ roaming: Boolean? = null,
): TestCase =
TestCase(
level = level ?: this.level,
@@ -166,7 +171,8 @@
carrierId = carrierId ?: this.carrierId,
inflateStrength = inflateStrength ?: this.inflateStrength,
activity = activity ?: this.activity,
- carrierNetworkChange = carrierNetworkChange ?: this.carrierNetworkChange
+ carrierNetworkChange = carrierNetworkChange ?: this.carrierNetworkChange,
+ roaming = roaming ?: this.roaming,
)
}
@@ -193,6 +199,8 @@
TelephonyManager.DATA_ACTIVITY_INOUT
)
private val carrierNetworkChange = booleanList
+ // false first so the base case doesn't have roaming set (more common)
+ private val roaming = listOf(false, true)
@Parameters(name = "{0}") @JvmStatic fun data() = testData()
@@ -226,7 +234,8 @@
carrierIds.first(),
inflateStrength.first(),
activity.first(),
- carrierNetworkChange.first()
+ carrierNetworkChange.first(),
+ roaming.first(),
)
val tail =
@@ -237,6 +246,7 @@
inflateStrength.map { baseCase.modifiedBy(inflateStrength = it) },
activity.map { baseCase.modifiedBy(activity = it) },
carrierNetworkChange.map { baseCase.modifiedBy(carrierNetworkChange = it) },
+ roaming.map { baseCase.modifiedBy(roaming = it) }
)
.flatten()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
index 32d0410..e4f29e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
@@ -292,6 +292,7 @@
assertThat(connectionInfo.dataActivityDirection).isEqualTo(model.activity)
assertThat(connectionInfo.carrierNetworkChangeActive)
.isEqualTo(model.carrierNetworkChange)
+ assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming)
// TODO(b/261029387) check these once we start handling them
assertThat(connectionInfo.isEmergencyOnly).isFalse()
@@ -313,6 +314,7 @@
inflateStrength: Boolean? = false,
activity: Int? = null,
carrierNetworkChange: Boolean = false,
+ roaming: Boolean = false,
): FakeNetworkEventModel =
FakeNetworkEventModel.Mobile(
level = level,
@@ -322,4 +324,5 @@
inflateStrength = inflateStrength,
activity = activity,
carrierNetworkChange = carrierNetworkChange,
+ roaming = roaming,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index 1fc9c60..0b3e5b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -32,6 +32,8 @@
import android.telephony.TelephonyManager.DATA_DISCONNECTED
import android.telephony.TelephonyManager.DATA_DISCONNECTING
import android.telephony.TelephonyManager.DATA_UNKNOWN
+import android.telephony.TelephonyManager.ERI_OFF
+import android.telephony.TelephonyManager.ERI_ON
import android.telephony.TelephonyManager.NETWORK_TYPE_LTE
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
import androidx.test.filters.SmallTest
@@ -402,6 +404,61 @@
job.cancel()
}
+ @Test
+ fun `roaming - cdma - queries telephony manager`() =
+ runBlocking(IMMEDIATE) {
+ var latest: Boolean? = null
+ // Start the telephony collection job so that cdmaRoaming starts updating
+ val telephonyJob = underTest.connectionInfo.launchIn(this)
+ val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this)
+
+ val cb = getTelephonyCallbackForType<ServiceStateListener>()
+
+ val serviceState = ServiceState()
+ serviceState.roaming = false
+
+ // CDMA roaming is off, GSM roaming is off
+ whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
+ cb.onServiceStateChanged(serviceState)
+
+ assertThat(latest).isFalse()
+
+ // CDMA roaming is off, GSM roaming is on
+ whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_ON)
+ cb.onServiceStateChanged(serviceState)
+
+ assertThat(latest).isTrue()
+
+ telephonyJob.cancel()
+ job.cancel()
+ }
+
+ @Test
+ fun `roaming - gsm - queries service state`() =
+ runBlocking(IMMEDIATE) {
+ var latest: Boolean? = null
+ val job = underTest.connectionInfo.onEach { latest = it.isRoaming }.launchIn(this)
+
+ val serviceState = ServiceState()
+ serviceState.roaming = false
+
+ val cb = getTelephonyCallbackForType<ServiceStateListener>()
+
+ // CDMA roaming is off, GSM roaming is off
+ whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
+ cb.onServiceStateChanged(serviceState)
+
+ assertThat(latest).isFalse()
+
+ // CDMA roaming is off, GSM roaming is on
+ serviceState.roaming = true
+ cb.onServiceStateChanged(serviceState)
+
+ assertThat(latest).isTrue()
+
+ job.cancel()
+ }
+
private fun getTelephonyCallbacks(): List<TelephonyCallback> {
val callbackCaptor = argumentCaptor<TelephonyCallback>()
Mockito.verify(telephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index 4b82b39..6d80acb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -23,6 +23,7 @@
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.provider.Settings
+import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.TelephonyCallback
@@ -30,6 +31,8 @@
import android.telephony.TelephonyManager
import androidx.test.filters.SmallTest
import com.android.internal.telephony.PhoneConstants
+import com.android.settingslib.R
+import com.android.settingslib.mobile.MobileMappings
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
@@ -50,6 +53,7 @@
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Assert.assertThrows
+import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentMatchers.anyInt
@@ -63,6 +67,7 @@
class MobileConnectionsRepositoryTest : SysuiTestCase() {
private lateinit var underTest: MobileConnectionsRepositoryImpl
+ private lateinit var connectionFactory: MobileConnectionRepositoryImpl.Factory
@Mock private lateinit var connectivityManager: ConnectivityManager
@Mock private lateinit var subscriptionManager: SubscriptionManager
@Mock private lateinit var telephonyManager: TelephonyManager
@@ -84,7 +89,7 @@
}
}
- val connectionFactory: MobileConnectionRepositoryImpl.Factory =
+ connectionFactory =
MobileConnectionRepositoryImpl.Factory(
context = context,
telephonyManager = telephonyManager,
@@ -385,6 +390,92 @@
job.cancel()
}
+ @Test
+ fun config_initiallyFromContext() =
+ runBlocking(IMMEDIATE) {
+ overrideResource(R.bool.config_showMin3G, true)
+ val configFromContext = MobileMappings.Config.readConfig(context)
+ assertThat(configFromContext.showAtLeast3G).isTrue()
+
+ // The initial value will be fetched when the repo is created, so we need to override
+ // the resources and then re-create the repo.
+ underTest =
+ MobileConnectionsRepositoryImpl(
+ connectivityManager,
+ subscriptionManager,
+ telephonyManager,
+ logger,
+ mobileMappings,
+ fakeBroadcastDispatcher,
+ globalSettings,
+ context,
+ IMMEDIATE,
+ scope,
+ connectionFactory,
+ )
+
+ var latest: MobileMappings.Config? = null
+ val job = underTest.defaultDataSubRatConfig.onEach { latest = it }.launchIn(this)
+
+ assertTrue(latest!!.areEqual(configFromContext))
+ assertTrue(latest!!.showAtLeast3G)
+
+ job.cancel()
+ }
+
+ @Test
+ fun config_subIdChangeEvent_updated() =
+ runBlocking(IMMEDIATE) {
+ var latest: MobileMappings.Config? = null
+ val job = underTest.defaultDataSubRatConfig.onEach { latest = it }.launchIn(this)
+ assertThat(latest!!.showAtLeast3G).isFalse()
+
+ overrideResource(R.bool.config_showMin3G, true)
+ val configFromContext = MobileMappings.Config.readConfig(context)
+ assertThat(configFromContext.showAtLeast3G).isTrue()
+
+ // WHEN the change event is fired
+ fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
+ receiver.onReceive(
+ context,
+ Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
+ )
+ }
+
+ // THEN the config is updated
+ assertTrue(latest!!.areEqual(configFromContext))
+ assertTrue(latest!!.showAtLeast3G)
+
+ job.cancel()
+ }
+
+ @Test
+ fun config_carrierConfigChangeEvent_updated() =
+ runBlocking(IMMEDIATE) {
+ var latest: MobileMappings.Config? = null
+ val job = underTest.defaultDataSubRatConfig.onEach { latest = it }.launchIn(this)
+ assertThat(latest!!.showAtLeast3G).isFalse()
+
+ overrideResource(R.bool.config_showMin3G, true)
+ val configFromContext = MobileMappings.Config.readConfig(context)
+ assertThat(configFromContext.showAtLeast3G).isTrue()
+
+ // WHEN the change event is fired
+ fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
+ receiver.onReceive(
+ context,
+ Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
+ )
+ }
+
+ // THEN the config is updated
+ assertThat(latest!!.areEqual(configFromContext)).isTrue()
+ assertThat(latest!!.showAtLeast3G).isTrue()
+
+ job.cancel()
+ }
+
private fun createCapabilities(connected: Boolean, validated: Boolean): NetworkCapabilities =
mock<NetworkCapabilities>().also {
whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(connected)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
index 3ae7d3c..0e2c38e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
@@ -22,12 +22,16 @@
import kotlinx.coroutines.flow.MutableStateFlow
class FakeMobileIconInteractor : MobileIconInteractor {
+ override val alwaysShowDataRatIcon = MutableStateFlow(false)
+
private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.THREE_G)
override val networkTypeIconGroup = _iconGroup
private val _isEmergencyOnly = MutableStateFlow(false)
override val isEmergencyOnly = _isEmergencyOnly
+ override val isRoaming = MutableStateFlow(false)
+
private val _isFailedConnection = MutableStateFlow(false)
override val isDefaultConnectionFailed = _isFailedConnection
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
index 0d4044d..9f300e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
@@ -54,6 +54,8 @@
private val _activeDataConnectionHasDataEnabled = MutableStateFlow(false)
override val activeDataConnectionHasDataEnabled = _activeDataConnectionHasDataEnabled
+ override val alwaysShowDataRatIcon = MutableStateFlow(false)
+
private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING)
override val defaultMobileIconMapping = _defaultMobileIconMapping
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index fd41b5b..9b6f6df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -59,6 +59,7 @@
MobileIconInteractorImpl(
scope,
mobileIconsInteractor.activeDataConnectionHasDataEnabled,
+ mobileIconsInteractor.alwaysShowDataRatIcon,
mobileIconsInteractor.defaultMobileIconMapping,
mobileIconsInteractor.defaultMobileIconGroup,
mobileIconsInteractor.isDefaultConnectionFailed,
@@ -223,6 +224,21 @@
}
@Test
+ fun alwaysShowDataRatIcon_matchesParent() =
+ runBlocking(IMMEDIATE) {
+ var latest: Boolean? = null
+ val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this)
+
+ mobileIconsInteractor.alwaysShowDataRatIcon.value = true
+ assertThat(latest).isTrue()
+
+ mobileIconsInteractor.alwaysShowDataRatIcon.value = false
+ assertThat(latest).isFalse()
+
+ job.cancel()
+ }
+
+ @Test
fun test_isDefaultDataEnabled_matchesParent() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
@@ -282,6 +298,100 @@
job.cancel()
}
+ @Test
+ fun `roaming - is gsm - uses connection model`() =
+ runBlocking(IMMEDIATE) {
+ var latest: Boolean? = null
+ val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
+
+ connectionRepository.cdmaRoaming.value = true
+ connectionRepository.setConnectionInfo(
+ MobileConnectionModel(
+ isGsm = true,
+ isRoaming = false,
+ )
+ )
+ yield()
+
+ assertThat(latest).isFalse()
+
+ connectionRepository.setConnectionInfo(
+ MobileConnectionModel(
+ isGsm = true,
+ isRoaming = true,
+ )
+ )
+ yield()
+
+ assertThat(latest).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun `roaming - is cdma - uses cdma roaming bit`() =
+ runBlocking(IMMEDIATE) {
+ var latest: Boolean? = null
+ val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
+
+ connectionRepository.cdmaRoaming.value = false
+ connectionRepository.setConnectionInfo(
+ MobileConnectionModel(
+ isGsm = false,
+ isRoaming = true,
+ )
+ )
+ yield()
+
+ assertThat(latest).isFalse()
+
+ connectionRepository.cdmaRoaming.value = true
+ connectionRepository.setConnectionInfo(
+ MobileConnectionModel(
+ isGsm = false,
+ isRoaming = false,
+ )
+ )
+ yield()
+
+ assertThat(latest).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun `roaming - false while carrierNetworkChangeActive`() =
+ runBlocking(IMMEDIATE) {
+ var latest: Boolean? = null
+ val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
+
+ connectionRepository.cdmaRoaming.value = true
+ connectionRepository.setConnectionInfo(
+ MobileConnectionModel(
+ isGsm = false,
+ isRoaming = true,
+ carrierNetworkChangeActive = true,
+ )
+ )
+ yield()
+
+ assertThat(latest).isFalse()
+
+ connectionRepository.cdmaRoaming.value = true
+ connectionRepository.setConnectionInfo(
+ MobileConnectionModel(
+ isGsm = true,
+ isRoaming = true,
+ carrierNetworkChangeActive = true,
+ )
+ )
+ yield()
+
+ assertThat(latest).isFalse()
+
+ job.cancel()
+ }
+
companion object {
private val IMMEDIATE = Dispatchers.Main.immediate
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index 58e57e2..8557894 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -18,6 +18,7 @@
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import androidx.test.filters.SmallTest
+import com.android.settingslib.mobile.MobileMappings
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
@@ -255,6 +256,38 @@
job.cancel()
}
+ @Test
+ fun alwaysShowDataRatIcon_configHasTrue() =
+ runBlocking(IMMEDIATE) {
+ var latest: Boolean? = null
+ val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this)
+
+ val config = MobileMappings.Config()
+ config.alwaysShowDataRatIcon = true
+ connectionsRepository.defaultDataSubRatConfig.value = config
+ yield()
+
+ assertThat(latest).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun alwaysShowDataRatIcon_configHasFalse() =
+ runBlocking(IMMEDIATE) {
+ var latest: Boolean? = null
+ val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this)
+
+ val config = MobileMappings.Config()
+ config.alwaysShowDataRatIcon = false
+ connectionsRepository.defaultDataSubRatConfig.value = config
+ yield()
+
+ assertThat(latest).isFalse()
+
+ job.cancel()
+ }
+
companion object {
private val IMMEDIATE = Dispatchers.Main.immediate
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index d4c2c3f..2c8f0a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -174,6 +174,82 @@
job.cancel()
}
+ @Test
+ fun networkType_alwaysShow_shownEvenWhenDisabled() =
+ runBlocking(IMMEDIATE) {
+ interactor.setIconGroup(THREE_G)
+ interactor.setIsDataEnabled(true)
+ interactor.alwaysShowDataRatIcon.value = true
+
+ var latest: Icon? = null
+ val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription)
+ )
+ assertThat(latest).isEqualTo(expected)
+
+ job.cancel()
+ }
+
+ @Test
+ fun networkType_alwaysShow_shownEvenWhenDisconnected() =
+ runBlocking(IMMEDIATE) {
+ interactor.setIconGroup(THREE_G)
+ interactor.isDataConnected.value = false
+ interactor.alwaysShowDataRatIcon.value = true
+
+ var latest: Icon? = null
+ val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription)
+ )
+ assertThat(latest).isEqualTo(expected)
+
+ job.cancel()
+ }
+
+ @Test
+ fun networkType_alwaysShow_shownEvenWhenFailedConnection() =
+ runBlocking(IMMEDIATE) {
+ interactor.setIconGroup(THREE_G)
+ interactor.setIsFailedConnection(true)
+ interactor.alwaysShowDataRatIcon.value = true
+
+ var latest: Icon? = null
+ val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription)
+ )
+ assertThat(latest).isEqualTo(expected)
+
+ job.cancel()
+ }
+
+ @Test
+ fun roaming() =
+ runBlocking(IMMEDIATE) {
+ interactor.isRoaming.value = true
+ var latest: Boolean? = null
+ val job = underTest.roaming.onEach { latest = it }.launchIn(this)
+
+ assertThat(latest).isTrue()
+
+ interactor.isRoaming.value = false
+
+ assertThat(latest).isFalse()
+
+ job.cancel()
+ }
+
/** Convenience constructor for these tests */
private fun defaultSignal(
level: Int = 1,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
index 2f18ce3..4e15b4a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
@@ -16,9 +16,9 @@
package com.android.systemui.statusbar.pipeline.wifi.data.repository
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT
-import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiActivityModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -35,7 +35,7 @@
override val wifiNetwork: StateFlow<WifiNetworkModel> = _wifiNetwork
private val _wifiActivity = MutableStateFlow(ACTIVITY_DEFAULT)
- override val wifiActivity: StateFlow<WifiActivityModel> = _wifiActivity
+ override val wifiActivity: StateFlow<DataActivityModel> = _wifiActivity
fun setIsWifiEnabled(enabled: Boolean) {
_isWifiEnabled.value = enabled
@@ -49,7 +49,7 @@
_wifiNetwork.value = wifiNetworkModel
}
- fun setWifiActivity(activity: WifiActivityModel) {
+ fun setWifiActivity(activity: DataActivityModel) {
_wifiActivity.value = activity
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
index 800f3c0..5d0d87b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
@@ -31,10 +31,10 @@
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
-import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiActivityModel
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
@@ -724,7 +724,7 @@
fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) {
underTest = createRepo(wifiManagerToUse = null)
- var latest: WifiActivityModel? = null
+ var latest: DataActivityModel? = null
val job = underTest
.wifiActivity
.onEach { latest = it }
@@ -737,7 +737,7 @@
@Test
fun wifiActivity_callbackGivesNone_activityFlowHasNone() = runBlocking(IMMEDIATE) {
- var latest: WifiActivityModel? = null
+ var latest: DataActivityModel? = null
val job = underTest
.wifiActivity
.onEach { latest = it }
@@ -746,7 +746,7 @@
getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_NONE)
assertThat(latest).isEqualTo(
- WifiActivityModel(hasActivityIn = false, hasActivityOut = false)
+ DataActivityModel(hasActivityIn = false, hasActivityOut = false)
)
job.cancel()
@@ -754,7 +754,7 @@
@Test
fun wifiActivity_callbackGivesIn_activityFlowHasIn() = runBlocking(IMMEDIATE) {
- var latest: WifiActivityModel? = null
+ var latest: DataActivityModel? = null
val job = underTest
.wifiActivity
.onEach { latest = it }
@@ -763,7 +763,7 @@
getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_IN)
assertThat(latest).isEqualTo(
- WifiActivityModel(hasActivityIn = true, hasActivityOut = false)
+ DataActivityModel(hasActivityIn = true, hasActivityOut = false)
)
job.cancel()
@@ -771,7 +771,7 @@
@Test
fun wifiActivity_callbackGivesOut_activityFlowHasOut() = runBlocking(IMMEDIATE) {
- var latest: WifiActivityModel? = null
+ var latest: DataActivityModel? = null
val job = underTest
.wifiActivity
.onEach { latest = it }
@@ -780,7 +780,7 @@
getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_OUT)
assertThat(latest).isEqualTo(
- WifiActivityModel(hasActivityIn = false, hasActivityOut = true)
+ DataActivityModel(hasActivityIn = false, hasActivityOut = true)
)
job.cancel()
@@ -788,7 +788,7 @@
@Test
fun wifiActivity_callbackGivesInout_activityFlowHasInAndOut() = runBlocking(IMMEDIATE) {
- var latest: WifiActivityModel? = null
+ var latest: DataActivityModel? = null
val job = underTest
.wifiActivity
.onEach { latest = it }
@@ -796,7 +796,7 @@
getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT)
- assertThat(latest).isEqualTo(WifiActivityModel(hasActivityIn = true, hasActivityOut = true))
+ assertThat(latest).isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = true))
job.cancel()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
index b38497a..2ecb17b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
@@ -20,10 +20,10 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
-import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiActivityModel
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -225,23 +225,23 @@
@Test
fun activity_matchesRepoWifiActivity() = runBlocking(IMMEDIATE) {
- var latest: WifiActivityModel? = null
+ var latest: DataActivityModel? = null
val job = underTest
.activity
.onEach { latest = it }
.launchIn(this)
- val activity1 = WifiActivityModel(hasActivityIn = true, hasActivityOut = true)
+ val activity1 = DataActivityModel(hasActivityIn = true, hasActivityOut = true)
wifiRepository.setWifiActivity(activity1)
yield()
assertThat(latest).isEqualTo(activity1)
- val activity2 = WifiActivityModel(hasActivityIn = false, hasActivityOut = false)
+ val activity2 = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
wifiRepository.setWifiActivity(activity2)
yield()
assertThat(latest).isEqualTo(activity2)
- val activity3 = WifiActivityModel(hasActivityIn = true, hasActivityOut = false)
+ val activity3 = DataActivityModel(hasActivityIn = true, hasActivityOut = false)
wifiRepository.setWifiActivity(activity3)
yield()
assertThat(latest).isEqualTo(activity3)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
index 22c0ea1..59c10cd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
@@ -52,6 +52,7 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -234,6 +235,7 @@
}
@Test
+ @Ignore("b/262660044")
fun onDarkChanged_iconHasNewColor() {
whenever(statusBarPipelineFlags.useWifiDebugColoring()).thenReturn(false)
val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
index 7502020..b47f177 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
@@ -27,13 +27,13 @@
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
-import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiActivityModel
import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
@@ -209,7 +209,7 @@
.launchIn(this)
// WHEN we update the repo to have activity
- val activity = WifiActivityModel(hasActivityIn = true, hasActivityOut = true)
+ val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
yield()
@@ -252,7 +252,7 @@
.launchIn(this)
// WHEN we update the repo to have activity
- val activity = WifiActivityModel(hasActivityIn = true, hasActivityOut = true)
+ val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
yield()
@@ -293,7 +293,7 @@
.onEach { latestQs = it }
.launchIn(this)
- val activity = WifiActivityModel(hasActivityIn = true, hasActivityOut = true)
+ val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
yield()
@@ -319,7 +319,7 @@
.onEach { latest = it }
.launchIn(this)
- val activity = WifiActivityModel(hasActivityIn = true, hasActivityOut = false)
+ val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false)
wifiRepository.setWifiActivity(activity)
yield()
@@ -341,7 +341,7 @@
.onEach { latest = it }
.launchIn(this)
- val activity = WifiActivityModel(hasActivityIn = false, hasActivityOut = true)
+ val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
yield()
@@ -363,7 +363,7 @@
.onEach { latest = it }
.launchIn(this)
- val activity = WifiActivityModel(hasActivityIn = false, hasActivityOut = true)
+ val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
yield()
@@ -385,7 +385,7 @@
.onEach { latest = it }
.launchIn(this)
- val activity = WifiActivityModel(hasActivityIn = true, hasActivityOut = false)
+ val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false)
wifiRepository.setWifiActivity(activity)
yield()
@@ -407,7 +407,7 @@
.onEach { latest = it }
.launchIn(this)
- val activity = WifiActivityModel(hasActivityIn = true, hasActivityOut = false)
+ val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false)
wifiRepository.setWifiActivity(activity)
yield()
@@ -429,7 +429,7 @@
.onEach { latest = it }
.launchIn(this)
- val activity = WifiActivityModel(hasActivityIn = false, hasActivityOut = true)
+ val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
yield()
@@ -451,7 +451,7 @@
.onEach { latest = it }
.launchIn(this)
- val activity = WifiActivityModel(hasActivityIn = true, hasActivityOut = true)
+ val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
yield()
@@ -473,7 +473,7 @@
.onEach { latest = it }
.launchIn(this)
- val activity = WifiActivityModel(hasActivityIn = false, hasActivityOut = false)
+ val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
wifiRepository.setWifiActivity(activity)
yield()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 915e999..2c47204 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -16,10 +16,14 @@
import static android.view.ContentInfo.SOURCE_CLIPBOARD;
+import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_STANDARD;
+
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -57,6 +61,7 @@
import android.window.WindowOnBackInvokedDispatcher;
import androidx.annotation.NonNull;
+import androidx.core.animation.AnimatorTestRule;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.UiEventLogger;
@@ -64,15 +69,19 @@
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.LightBarController;
import org.junit.After;
import org.junit.Before;
+import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -99,6 +108,9 @@
private BlockingQueueIntentReceiver mReceiver;
private final UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake();
+ @ClassRule
+ public static AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule();
+
@Before
public void setUp() throws Exception {
allowTestableLooperAsMainThread();
@@ -294,6 +306,9 @@
/* invoke the captured callback */
onBackInvokedCallbackCaptor.getValue().onBackInvoked();
+ /* wait for RemoteInputView disappear animation to finish */
+ mAnimatorTestRule.advanceTimeBy(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+
/* verify that the RemoteInputView goes away */
assertEquals(view.getVisibility(), View.GONE);
}
@@ -363,19 +378,73 @@
mUiEventLoggerFake.eventId(1));
}
+ @Test
+ public void testFocusAnimation() throws Exception {
+ NotificationTestHelper helper = new NotificationTestHelper(
+ mContext,
+ mDependency,
+ TestableLooper.get(this));
+ ExpandableNotificationRow row = helper.createRow();
+ RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
+ bindController(view, row.getEntry());
+ view.setVisibility(View.GONE);
+
+ View crossFadeView = new View(mContext);
+
+ // Start focus animation
+ view.focusAnimated(crossFadeView);
+
+ assertTrue(view.isAnimatingAppearance());
+
+ // fast forward to end of animation
+ mAnimatorTestRule.advanceTimeBy(ANIMATION_DURATION_STANDARD);
+
+ // assert that crossFadeView's alpha is reset to 1f after the animation (hidden behind
+ // RemoteInputView)
+ assertEquals(1f, crossFadeView.getAlpha());
+ assertFalse(view.isAnimatingAppearance());
+ assertEquals(View.VISIBLE, view.getVisibility());
+ assertEquals(1f, view.getAlpha());
+ }
+
+ @Test
+ public void testDefocusAnimation() throws Exception {
+ NotificationTestHelper helper = new NotificationTestHelper(
+ mContext,
+ mDependency,
+ TestableLooper.get(this));
+ ExpandableNotificationRow row = helper.createRow();
+ RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
+ bindController(view, row.getEntry());
+
+ // Start defocus animation
+ view.onDefocus(true, false);
+ assertEquals(View.VISIBLE, view.getVisibility());
+
+ // fast forward to end of animation
+ mAnimatorTestRule.advanceTimeBy(ANIMATION_DURATION_STANDARD);
+
+ // assert that RemoteInputView is no longer visible
+ assertEquals(View.GONE, view.getVisibility());
+ }
+
// NOTE: because we're refactoring the RemoteInputView and moving logic into the
- // RemoteInputViewController, it's easiest to just test the system of the two classes together.
+ // RemoteInputViewController, it's easiest to just test the system of the two classes together.
@NonNull
private RemoteInputViewController bindController(
RemoteInputView view,
NotificationEntry entry) {
+ FakeFeatureFlags fakeFeatureFlags = new FakeFeatureFlags();
+ fakeFeatureFlags.set(Flags.NOTIFICATION_INLINE_REPLY_ANIMATION, true);
RemoteInputViewControllerImpl viewController = new RemoteInputViewControllerImpl(
view,
entry,
mRemoteInputQuickSettingsDisabler,
mController,
mShortcutManager,
- mUiEventLoggerFake);
+ mUiEventLoggerFake,
+ fakeFeatureFlags
+ );
viewController.bind();
return viewController;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS
new file mode 100644
index 0000000..7ccb316
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 1254381
+azappone@google.com
+achalke@google.com
+juliacr@google.com
+madym@google.com
+mgalhardo@google.com
+petrcermak@google.com
+vanjan@google.com
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt
new file mode 100644
index 0000000..8dd088f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.stylus
+
+import android.content.Context
+import android.hardware.BatteryState
+import android.hardware.input.InputManager
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.view.InputDevice
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@Ignore("TODO(b/20579491): unignore on main")
+class StylusFirstUsageListenerTest : SysuiTestCase() {
+ @Mock lateinit var context: Context
+ @Mock lateinit var inputManager: InputManager
+ @Mock lateinit var stylusManager: StylusManager
+ @Mock lateinit var featureFlags: FeatureFlags
+ @Mock lateinit var internalStylusDevice: InputDevice
+ @Mock lateinit var otherDevice: InputDevice
+ @Mock lateinit var externalStylusDevice: InputDevice
+ @Mock lateinit var batteryState: BatteryState
+ @Mock lateinit var handler: Handler
+
+ private lateinit var stylusListener: StylusFirstUsageListener
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(true)
+ whenever(inputManager.isStylusEverUsed(context)).thenReturn(false)
+
+ stylusListener =
+ StylusFirstUsageListener(
+ context,
+ inputManager,
+ stylusManager,
+ featureFlags,
+ EXECUTOR,
+ handler
+ )
+ stylusListener.hasStarted = false
+
+ whenever(handler.post(any())).thenAnswer {
+ (it.arguments[0] as Runnable).run()
+ true
+ }
+
+ whenever(otherDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(false)
+ whenever(internalStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
+ whenever(internalStylusDevice.isExternal).thenReturn(false)
+ whenever(externalStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
+ whenever(externalStylusDevice.isExternal).thenReturn(true)
+
+ whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf())
+ whenever(inputManager.getInputDevice(OTHER_DEVICE_ID)).thenReturn(otherDevice)
+ whenever(inputManager.getInputDevice(INTERNAL_STYLUS_DEVICE_ID))
+ .thenReturn(internalStylusDevice)
+ whenever(inputManager.getInputDevice(EXTERNAL_STYLUS_DEVICE_ID))
+ .thenReturn(externalStylusDevice)
+ }
+
+ @Test
+ fun start_flagDisabled_doesNotRegister() {
+ whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(false)
+
+ stylusListener.start()
+
+ verify(stylusManager, never()).registerCallback(any())
+ verify(inputManager, never()).setStylusEverUsed(context, true)
+ }
+
+ @Test
+ fun start_toggleHasStarted() {
+ stylusListener.start()
+
+ assert(stylusListener.hasStarted)
+ }
+
+ @Test
+ fun start_hasStarted_doesNotRegister() {
+ stylusListener.hasStarted = true
+
+ stylusListener.start()
+
+ verify(stylusManager, never()).registerCallback(any())
+ }
+
+ @Test
+ fun start_hostDeviceDoesNotSupportStylus_doesNotRegister() {
+ whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(OTHER_DEVICE_ID))
+
+ stylusListener.start()
+
+ verify(stylusManager, never()).registerCallback(any())
+ verify(inputManager, never()).setStylusEverUsed(context, true)
+ }
+
+ @Test
+ fun start_stylusEverUsed_doesNotRegister() {
+ whenever(inputManager.inputDeviceIds)
+ .thenReturn(intArrayOf(OTHER_DEVICE_ID, INTERNAL_STYLUS_DEVICE_ID))
+ whenever(inputManager.isStylusEverUsed(context)).thenReturn(true)
+
+ stylusListener.start()
+
+ verify(stylusManager, never()).registerCallback(any())
+ verify(inputManager, never()).setStylusEverUsed(context, true)
+ }
+
+ @Test
+ fun start_hostDeviceSupportsStylus_registersListener() {
+ whenever(inputManager.inputDeviceIds)
+ .thenReturn(intArrayOf(OTHER_DEVICE_ID, INTERNAL_STYLUS_DEVICE_ID))
+
+ stylusListener.start()
+
+ verify(stylusManager).registerCallback(any())
+ verify(inputManager, never()).setStylusEverUsed(context, true)
+ }
+
+ @Test
+ fun onStylusAdded_hasNotStarted_doesNotRegisterListener() {
+ stylusListener.hasStarted = false
+
+ stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
+
+ verifyZeroInteractions(inputManager)
+ }
+
+ @Test
+ fun onStylusAdded_internalStylus_registersListener() {
+ stylusListener.hasStarted = true
+
+ stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
+
+ verify(inputManager, times(1))
+ .addInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, EXECUTOR, stylusListener)
+ }
+
+ @Test
+ fun onStylusAdded_externalStylus_doesNotRegisterListener() {
+ stylusListener.hasStarted = true
+
+ stylusListener.onStylusAdded(EXTERNAL_STYLUS_DEVICE_ID)
+
+ verify(inputManager, never()).addInputDeviceBatteryListener(any(), any(), any())
+ }
+
+ @Test
+ fun onStylusAdded_otherDevice_doesNotRegisterListener() {
+ stylusListener.onStylusAdded(OTHER_DEVICE_ID)
+
+ verify(inputManager, never()).addInputDeviceBatteryListener(any(), any(), any())
+ }
+
+ @Test
+ fun onStylusRemoved_registeredDevice_unregistersListener() {
+ stylusListener.hasStarted = true
+ stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
+
+ stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
+
+ verify(inputManager, times(1))
+ .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
+ }
+
+ @Test
+ fun onStylusRemoved_hasNotStarted_doesNotUnregisterListener() {
+ stylusListener.hasStarted = false
+ stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
+
+ stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
+
+ verifyZeroInteractions(inputManager)
+ }
+
+ @Test
+ fun onStylusRemoved_unregisteredDevice_doesNotUnregisterListener() {
+ stylusListener.hasStarted = true
+
+ stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
+
+ verifyNoMoreInteractions(inputManager)
+ }
+
+ @Test
+ fun onStylusBluetoothConnected_updateStylusFlagAndUnregisters() {
+ stylusListener.hasStarted = true
+ stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
+
+ stylusListener.onStylusBluetoothConnected(EXTERNAL_STYLUS_DEVICE_ID, "ANY")
+
+ verify(inputManager).setStylusEverUsed(context, true)
+ verify(inputManager, times(1))
+ .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
+ verify(stylusManager).unregisterCallback(stylusListener)
+ }
+
+ @Test
+ fun onStylusBluetoothConnected_hasNotStarted_doesNoting() {
+ stylusListener.hasStarted = false
+ stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
+
+ stylusListener.onStylusBluetoothConnected(EXTERNAL_STYLUS_DEVICE_ID, "ANY")
+
+ verifyZeroInteractions(inputManager)
+ verifyZeroInteractions(stylusManager)
+ }
+
+ @Test
+ fun onBatteryStateChanged_batteryPresent_updateStylusFlagAndUnregisters() {
+ stylusListener.hasStarted = true
+ stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
+ whenever(batteryState.isPresent).thenReturn(true)
+
+ stylusListener.onBatteryStateChanged(0, 1, batteryState)
+
+ verify(inputManager).setStylusEverUsed(context, true)
+ verify(inputManager, times(1))
+ .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
+ verify(stylusManager).unregisterCallback(stylusListener)
+ }
+
+ @Test
+ fun onBatteryStateChanged_batteryNotPresent_doesNotUpdateFlagOrUnregister() {
+ stylusListener.hasStarted = true
+ stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
+ whenever(batteryState.isPresent).thenReturn(false)
+
+ stylusListener.onBatteryStateChanged(0, 1, batteryState)
+
+ verifyZeroInteractions(stylusManager)
+ verify(inputManager, never())
+ .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
+ }
+
+ @Test
+ fun onBatteryStateChanged_hasNotStarted_doesNothing() {
+ stylusListener.hasStarted = false
+ stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
+ whenever(batteryState.isPresent).thenReturn(false)
+
+ stylusListener.onBatteryStateChanged(0, 1, batteryState)
+
+ verifyZeroInteractions(inputManager)
+ verifyZeroInteractions(stylusManager)
+ }
+
+ companion object {
+ private const val OTHER_DEVICE_ID = 0
+ private const val INTERNAL_STYLUS_DEVICE_ID = 1
+ private const val EXTERNAL_STYLUS_DEVICE_ID = 2
+ private val EXECUTOR = FakeExecutor(FakeSystemClock())
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
new file mode 100644
index 0000000..ff382a3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.stylus
+
+import android.hardware.BatteryState
+import android.hardware.input.InputManager
+import android.testing.AndroidTestingRunner
+import android.view.InputDevice
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.util.mockito.whenever
+import java.util.concurrent.Executor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class StylusUsiPowerStartableTest : SysuiTestCase() {
+ @Mock lateinit var inputManager: InputManager
+ @Mock lateinit var stylusManager: StylusManager
+ @Mock lateinit var stylusDevice: InputDevice
+ @Mock lateinit var externalDevice: InputDevice
+ @Mock lateinit var featureFlags: FeatureFlags
+ @Mock lateinit var stylusUsiPowerUi: StylusUsiPowerUI
+
+ lateinit var startable: StylusUsiPowerStartable
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ startable =
+ StylusUsiPowerStartable(
+ stylusManager,
+ inputManager,
+ stylusUsiPowerUi,
+ featureFlags,
+ DIRECT_EXECUTOR,
+ )
+
+ whenever(featureFlags.isEnabled(Flags.ENABLE_USI_BATTERY_NOTIFICATIONS)).thenReturn(true)
+
+ whenever(inputManager.getInputDevice(EXTERNAL_DEVICE_ID)).thenReturn(externalDevice)
+ whenever(inputManager.getInputDevice(STYLUS_DEVICE_ID)).thenReturn(stylusDevice)
+ whenever(inputManager.inputDeviceIds)
+ .thenReturn(intArrayOf(EXTERNAL_DEVICE_ID, STYLUS_DEVICE_ID))
+
+ whenever(stylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
+ whenever(stylusDevice.isExternal).thenReturn(false)
+ whenever(stylusDevice.id).thenReturn(STYLUS_DEVICE_ID)
+ whenever(externalDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
+ whenever(externalDevice.isExternal).thenReturn(true)
+ whenever(externalDevice.id).thenReturn(EXTERNAL_DEVICE_ID)
+ }
+
+ @Test
+ fun start_addsBatteryListenerForInternalStylus() {
+ startable.start()
+
+ verify(inputManager, times(1))
+ .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
+ }
+
+ @Test
+ fun onStylusAdded_internalStylus_addsBatteryListener() {
+ startable.onStylusAdded(STYLUS_DEVICE_ID)
+
+ verify(inputManager, times(1))
+ .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
+ }
+
+ @Test
+ fun onStylusAdded_externalStylus_doesNotAddBatteryListener() {
+ startable.onStylusAdded(EXTERNAL_DEVICE_ID)
+
+ verify(inputManager, never())
+ .addInputDeviceBatteryListener(EXTERNAL_DEVICE_ID, DIRECT_EXECUTOR, startable)
+ }
+
+ @Test
+ fun onStylusRemoved_registeredStylus_removesBatteryListener() {
+ startable.onStylusAdded(STYLUS_DEVICE_ID)
+ startable.onStylusRemoved(STYLUS_DEVICE_ID)
+
+ inOrder(inputManager).let {
+ it.verify(inputManager, times(1))
+ .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
+ it.verify(inputManager, times(1))
+ .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, startable)
+ }
+ }
+
+ @Test
+ fun onStylusBluetoothConnected_refreshesNotification() {
+ startable.onStylusBluetoothConnected(STYLUS_DEVICE_ID, "ANY")
+
+ verify(stylusUsiPowerUi, times(1)).refresh()
+ }
+
+ @Test
+ fun onStylusBluetoothDisconnected_refreshesNotification() {
+ startable.onStylusBluetoothDisconnected(STYLUS_DEVICE_ID, "ANY")
+
+ verify(stylusUsiPowerUi, times(1)).refresh()
+ }
+
+ @Test
+ fun onBatteryStateChanged_batteryPresent_refreshesNotification() {
+ val batteryState = mock(BatteryState::class.java)
+ whenever(batteryState.isPresent).thenReturn(true)
+
+ startable.onBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
+
+ verify(stylusUsiPowerUi, times(1)).updateBatteryState(batteryState)
+ }
+
+ @Test
+ fun onBatteryStateChanged_batteryNotPresent_noop() {
+ val batteryState = mock(BatteryState::class.java)
+ whenever(batteryState.isPresent).thenReturn(false)
+
+ startable.onBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
+
+ verifyNoMoreInteractions(stylusUsiPowerUi)
+ }
+
+ companion object {
+ private val DIRECT_EXECUTOR = Executor { r -> r.run() }
+
+ private const val EXTERNAL_DEVICE_ID = 0
+ private const val STYLUS_DEVICE_ID = 1
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
new file mode 100644
index 0000000..5987550
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.stylus
+
+import android.hardware.BatteryState
+import android.hardware.input.InputManager
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.view.InputDevice
+import androidx.core.app.NotificationManagerCompat
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class StylusUsiPowerUiTest : SysuiTestCase() {
+ @Mock lateinit var notificationManager: NotificationManagerCompat
+ @Mock lateinit var inputManager: InputManager
+ @Mock lateinit var handler: Handler
+ @Mock lateinit var btStylusDevice: InputDevice
+
+ private lateinit var stylusUsiPowerUi: StylusUsiPowerUI
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ whenever(handler.post(any())).thenAnswer {
+ (it.arguments[0] as Runnable).run()
+ true
+ }
+
+ whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf())
+ whenever(inputManager.getInputDevice(0)).thenReturn(btStylusDevice)
+ whenever(btStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
+ // whenever(btStylusDevice.bluetoothAddress).thenReturn("SO:ME:AD:DR:ES")
+
+ stylusUsiPowerUi = StylusUsiPowerUI(mContext, notificationManager, inputManager, handler)
+ }
+
+ @Test
+ fun updateBatteryState_capacityBelowThreshold_notifies() {
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+
+ verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
+ verifyNoMoreInteractions(notificationManager)
+ }
+
+ @Test
+ fun updateBatteryState_capacityAboveThreshold_cancelsNotificattion() {
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.8f))
+
+ verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+ verifyNoMoreInteractions(notificationManager)
+ }
+
+ @Test
+ fun updateBatteryState_existingNotification_capacityAboveThreshold_cancelsNotification() {
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.8f))
+
+ inOrder(notificationManager).let {
+ it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
+ it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+ it.verifyNoMoreInteractions()
+ }
+ }
+
+ @Test
+ fun updateBatteryState_existingNotification_capacityBelowThreshold_updatesNotification() {
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.15f))
+
+ verify(notificationManager, times(2)).notify(eq(R.string.stylus_battery_low), any())
+ verifyNoMoreInteractions(notificationManager)
+ }
+
+ @Test
+ fun updateBatteryState_capacityAboveThenBelowThreshold_hidesThenShowsNotification() {
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.5f))
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+
+ inOrder(notificationManager).let {
+ it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
+ it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+ it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
+ it.verifyNoMoreInteractions()
+ }
+ }
+
+ @Test
+ fun updateSuppression_noExistingNotification_cancelsNotification() {
+ stylusUsiPowerUi.updateSuppression(true)
+
+ verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+ verifyNoMoreInteractions(notificationManager)
+ }
+
+ @Test
+ fun updateSuppression_existingNotification_cancelsNotification() {
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+
+ stylusUsiPowerUi.updateSuppression(true)
+
+ inOrder(notificationManager).let {
+ it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
+ it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+ it.verifyNoMoreInteractions()
+ }
+ }
+
+ @Test
+ @Ignore("TODO(b/257936830): get bt address once input api available")
+ fun refresh_hasConnectedBluetoothStylus_doesNotNotify() {
+ whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(0))
+
+ stylusUsiPowerUi.refresh()
+
+ verifyNoMoreInteractions(notificationManager)
+ }
+
+ @Test
+ @Ignore("TODO(b/257936830): get bt address once input api available")
+ fun refresh_hasConnectedBluetoothStylus_existingNotification_cancelsNotification() {
+ stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
+ whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(0))
+
+ stylusUsiPowerUi.refresh()
+
+ verify(notificationManager).cancel(R.string.stylus_battery_low)
+ }
+
+ class FixedCapacityBatteryState(private val capacity: Float) : BatteryState() {
+ override fun getCapacity() = capacity
+ override fun getStatus() = 0
+ override fun isPresent() = true
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
index 09f0d4a..99e2012 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
@@ -27,6 +27,7 @@
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
import com.android.systemui.util.concurrency.DelayableExecutor
@@ -35,6 +36,7 @@
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.wakelock.WakeLock
import com.android.systemui.util.wakelock.WakeLockFake
import com.google.common.truth.Truth.assertThat
@@ -59,12 +61,14 @@
private lateinit var fakeWakeLock: WakeLockFake
@Mock
- private lateinit var logger: TemporaryViewLogger
+ private lateinit var logger: TemporaryViewLogger<ViewInfo>
@Mock
private lateinit var accessibilityManager: AccessibilityManager
@Mock
private lateinit var configurationController: ConfigurationController
@Mock
+ private lateinit var dumpManager: DumpManager
+ @Mock
private lateinit var windowManager: WindowManager
@Mock
private lateinit var powerManager: PowerManager
@@ -74,7 +78,7 @@
MockitoAnnotations.initMocks(this)
whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any()))
- .thenReturn(TIMEOUT_MS.toInt())
+ .thenAnswer { it.arguments[0] }
fakeClock = FakeSystemClock()
fakeExecutor = FakeExecutor(fakeClock)
@@ -84,14 +88,16 @@
fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
underTest = TestController(
- context,
- logger,
- windowManager,
- fakeExecutor,
- accessibilityManager,
- configurationController,
- powerManager,
- fakeWakeLockBuilder,
+ context,
+ logger,
+ windowManager,
+ fakeExecutor,
+ accessibilityManager,
+ configurationController,
+ dumpManager,
+ powerManager,
+ fakeWakeLockBuilder,
+ fakeClock,
)
underTest.start()
}
@@ -112,14 +118,14 @@
@Test
fun displayView_logged() {
- underTest.displayView(
- ViewInfo(
- name = "name",
- windowTitle = "Fake Window Title",
- )
+ val info = ViewInfo(
+ name = "name",
+ windowTitle = "Fake Window Title",
)
- verify(logger).logViewAddition("id", "Fake Window Title")
+ underTest.displayView(info)
+
+ verify(logger).logViewAddition(info)
}
@Test
@@ -168,10 +174,11 @@
}
@Test
- fun displayView_twiceWithDifferentWindowTitles_oldViewRemovedNewViewAdded() {
+ fun displayView_twiceWithDifferentIds_oldViewRemovedNewViewAdded() {
underTest.displayView(
ViewInfo(
name = "name",
+ id = "First",
windowTitle = "First Fake Window Title",
)
)
@@ -179,6 +186,7 @@
underTest.displayView(
ViewInfo(
name = "name",
+ id = "Second",
windowTitle = "Second Fake Window Title",
)
)
@@ -263,19 +271,69 @@
}
@Test
+ fun viewUpdatedWithNewOnViewTimeoutRunnable_newRunnableUsed() {
+ var runnable1Run = false
+ underTest.displayView(ViewInfo(name = "name", id = "id1", windowTitle = "1")) {
+ runnable1Run = true
+ }
+
+ var runnable2Run = false
+ underTest.displayView(ViewInfo(name = "name", id = "id1", windowTitle = "1")) {
+ runnable2Run = true
+ }
+
+ fakeClock.advanceTime(TIMEOUT_MS + 1)
+
+ assertThat(runnable1Run).isFalse()
+ assertThat(runnable2Run).isTrue()
+ }
+
+ @Test
+ fun multipleViewsWithDifferentIds_moreRecentReplacesOlder() {
+ underTest.displayView(
+ ViewInfo(
+ name = "name",
+ windowTitle = "First Fake Window Title",
+ id = "id1"
+ )
+ )
+
+ underTest.displayView(
+ ViewInfo(
+ name = "name",
+ windowTitle = "Second Fake Window Title",
+ id = "id2"
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+
+ verify(windowManager, times(2)).addView(capture(viewCaptor), capture(windowParamsCaptor))
+
+ assertThat(windowParamsCaptor.allValues[0].title).isEqualTo("First Fake Window Title")
+ assertThat(windowParamsCaptor.allValues[1].title).isEqualTo("Second Fake Window Title")
+ verify(windowManager).removeView(viewCaptor.allValues[0])
+ verify(configurationController, never()).removeCallback(any())
+ }
+
+ @Test
fun multipleViewsWithDifferentIds_recentActiveViewIsDisplayed() {
underTest.displayView(ViewInfo("First name", id = "id1"))
verify(windowManager).addView(any(), any())
-
reset(windowManager)
+
underTest.displayView(ViewInfo("Second name", id = "id2"))
+
+ verify(windowManager).removeView(any())
+ verify(windowManager).addView(any(), any())
+ reset(windowManager)
+
underTest.removeView("id2", "test reason")
verify(windowManager).removeView(any())
-
- fakeClock.advanceTime(DISPLAY_VIEW_DELAY + 1)
-
+ verify(windowManager).addView(any(), any())
assertThat(underTest.mostRecentViewInfo?.id).isEqualTo("id1")
assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("First name")
@@ -284,6 +342,7 @@
verify(windowManager).removeView(any())
assertThat(underTest.activeViews.size).isEqualTo(0)
+ verify(configurationController).removeCallback(any())
}
@Test
@@ -291,19 +350,28 @@
underTest.displayView(ViewInfo("First name", id = "id1"))
verify(windowManager).addView(any(), any())
-
reset(windowManager)
+
underTest.displayView(ViewInfo("Second name", id = "id2"))
+
+ verify(windowManager).removeView(any())
+ verify(windowManager).addView(any(), any())
+ reset(windowManager)
+
+ // WHEN an old view is removed
underTest.removeView("id1", "test reason")
+ // THEN we don't update anything
verify(windowManager, never()).removeView(any())
assertThat(underTest.mostRecentViewInfo?.id).isEqualTo("id2")
assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("Second name")
+ verify(configurationController, never()).removeCallback(any())
fakeClock.advanceTime(TIMEOUT_MS + 1)
verify(windowManager).removeView(any())
assertThat(underTest.activeViews.size).isEqualTo(0)
+ verify(configurationController).removeCallback(any())
}
@Test
@@ -312,33 +380,31 @@
underTest.displayView(ViewInfo("Second name", id = "id2"))
underTest.displayView(ViewInfo("Third name", id = "id3"))
- verify(windowManager).addView(any(), any())
+ verify(windowManager, times(3)).addView(any(), any())
+ verify(windowManager, times(2)).removeView(any())
reset(windowManager)
underTest.removeView("id3", "test reason")
verify(windowManager).removeView(any())
-
- fakeClock.advanceTime(DISPLAY_VIEW_DELAY + 1)
-
assertThat(underTest.mostRecentViewInfo?.id).isEqualTo("id2")
assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("Second name")
+ verify(configurationController, never()).removeCallback(any())
reset(windowManager)
underTest.removeView("id2", "test reason")
verify(windowManager).removeView(any())
-
- fakeClock.advanceTime(DISPLAY_VIEW_DELAY + 1)
-
assertThat(underTest.mostRecentViewInfo?.id).isEqualTo("id1")
assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("First name")
+ verify(configurationController, never()).removeCallback(any())
reset(windowManager)
fakeClock.advanceTime(TIMEOUT_MS + 1)
verify(windowManager).removeView(any())
assertThat(underTest.activeViews.size).isEqualTo(0)
+ verify(configurationController).removeCallback(any())
}
@Test
@@ -347,18 +413,21 @@
underTest.displayView(ViewInfo("New name", id = "id1"))
verify(windowManager).addView(any(), any())
-
reset(windowManager)
+
underTest.displayView(ViewInfo("Second name", id = "id2"))
+
+ verify(windowManager).removeView(any())
+ verify(windowManager).addView(any(), any())
+ reset(windowManager)
+
underTest.removeView("id2", "test reason")
verify(windowManager).removeView(any())
-
- fakeClock.advanceTime(DISPLAY_VIEW_DELAY + 1)
-
+ verify(windowManager).addView(any(), any())
assertThat(underTest.mostRecentViewInfo?.id).isEqualTo("id1")
assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("New name")
- assertThat(underTest.activeViews[0].second.name).isEqualTo("New name")
+ assertThat(underTest.activeViews[0].info.name).isEqualTo("New name")
reset(windowManager)
fakeClock.advanceTime(TIMEOUT_MS + 1)
@@ -368,19 +437,523 @@
}
@Test
- fun multipleViewsWithDifferentIds_viewsTimeouts_noViewLeftToDisplay() {
- underTest.displayView(ViewInfo("First name", id = "id1"))
- fakeClock.advanceTime(TIMEOUT_MS / 3)
- underTest.displayView(ViewInfo("Second name", id = "id2"))
- fakeClock.advanceTime(TIMEOUT_MS / 3)
- underTest.displayView(ViewInfo("Third name", id = "id3"))
+ fun multipleViews_mostRecentViewRemoved_otherViewsTimedOutAndNotDisplayed() {
+ underTest.displayView(ViewInfo("First name", id = "id1", timeoutMs = 4000))
+ fakeClock.advanceTime(1000)
+ underTest.displayView(ViewInfo("Second name", id = "id2", timeoutMs = 4000))
+ fakeClock.advanceTime(1000)
+ underTest.displayView(ViewInfo("Third name", id = "id3", timeoutMs = 20000))
reset(windowManager)
- fakeClock.advanceTime(TIMEOUT_MS + 1)
+ fakeClock.advanceTime(20000 + 1)
verify(windowManager).removeView(any())
verify(windowManager, never()).addView(any(), any())
assertThat(underTest.activeViews.size).isEqualTo(0)
+ verify(configurationController).removeCallback(any())
+ }
+
+ @Test
+ fun multipleViews_mostRecentViewRemoved_viewWithShortTimeLeftNotDisplayed() {
+ underTest.displayView(ViewInfo("First name", id = "id1", timeoutMs = 4000))
+ fakeClock.advanceTime(1000)
+ underTest.displayView(ViewInfo("Second name", id = "id2", timeoutMs = 2500))
+
+ reset(windowManager)
+ fakeClock.advanceTime(2500 + 1)
+ // At this point, 3501ms have passed, so id1 only has 499ms left which is not enough.
+ // So, it shouldn't be displayed.
+
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(underTest.activeViews.size).isEqualTo(0)
+ verify(configurationController).removeCallback(any())
+ }
+
+ @Test
+ fun lowerThenHigherPriority_higherReplacesLower() {
+ underTest.displayView(
+ ViewInfo(
+ name = "normal",
+ windowTitle = "Normal Window Title",
+ id = "normal",
+ priority = ViewPriority.NORMAL,
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title")
+ reset(windowManager)
+
+ underTest.displayView(
+ ViewInfo(
+ name = "critical",
+ windowTitle = "Critical Window Title",
+ id = "critical",
+ priority = ViewPriority.CRITICAL,
+ )
+ )
+
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Critical Window Title")
+ verify(configurationController, never()).removeCallback(any())
+ }
+
+ @Test
+ fun lowerThenHigherPriority_lowerPriorityRedisplayed() {
+ underTest.displayView(
+ ViewInfo(
+ name = "normal",
+ windowTitle = "Normal Window Title",
+ id = "normal",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 10000
+ )
+ )
+
+ underTest.displayView(
+ ViewInfo(
+ name = "critical",
+ windowTitle = "Critical Window Title",
+ id = "critical",
+ priority = ViewPriority.CRITICAL,
+ timeoutMs = 2000
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager, times(2)).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.allValues[0].title).isEqualTo("Normal Window Title")
+ assertThat(windowParamsCaptor.allValues[1].title).isEqualTo("Critical Window Title")
+ verify(windowManager).removeView(viewCaptor.allValues[0])
+
+ reset(windowManager)
+
+ // WHEN the critical's timeout has expired
+ fakeClock.advanceTime(2000 + 1)
+
+ // THEN the normal view is re-displayed
+ verify(windowManager).removeView(viewCaptor.allValues[1])
+ verify(windowManager).addView(any(), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title")
+ verify(configurationController, never()).removeCallback(any())
+ }
+
+ @Test
+ fun lowerThenHigherPriority_lowerPriorityNotRedisplayedBecauseTimedOut() {
+ underTest.displayView(
+ ViewInfo(
+ name = "normal",
+ windowTitle = "Normal Window Title",
+ id = "normal",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 1000
+ )
+ )
+
+ underTest.displayView(
+ ViewInfo(
+ name = "critical",
+ windowTitle = "Critical Window Title",
+ id = "critical",
+ priority = ViewPriority.CRITICAL,
+ timeoutMs = 2000
+ )
+ )
+ reset(windowManager)
+
+ // WHEN the critical's timeout has expired
+ fakeClock.advanceTime(2000 + 1)
+
+ // THEN the normal view is not re-displayed since it already timed out
+ verify(windowManager).removeView(any())
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(underTest.activeViews).isEmpty()
+ verify(configurationController).removeCallback(any())
+ }
+
+ @Test
+ fun higherThenLowerPriority_higherStaysDisplayed() {
+ underTest.displayView(
+ ViewInfo(
+ name = "critical",
+ windowTitle = "Critical Window Title",
+ id = "critical",
+ priority = ViewPriority.CRITICAL,
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Critical Window Title")
+ reset(windowManager)
+
+ underTest.displayView(
+ ViewInfo(
+ name = "normal",
+ windowTitle = "Normal Window Title",
+ id = "normal",
+ priority = ViewPriority.NORMAL,
+ )
+ )
+
+ verify(windowManager, never()).removeView(viewCaptor.value)
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+ verify(configurationController, never()).removeCallback(any())
+ }
+
+ @Test
+ fun higherThenLowerPriority_lowerEventuallyDisplayed() {
+ underTest.displayView(
+ ViewInfo(
+ name = "critical",
+ windowTitle = "Critical Window Title",
+ id = "critical",
+ priority = ViewPriority.CRITICAL,
+ timeoutMs = 3000,
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Critical Window Title")
+ reset(windowManager)
+
+ underTest.displayView(
+ ViewInfo(
+ name = "normal",
+ windowTitle = "Normal Window Title",
+ id = "normal",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 5000,
+ )
+ )
+
+ verify(windowManager, never()).removeView(viewCaptor.value)
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+
+ // WHEN the first critical view has timed out
+ fakeClock.advanceTime(3000 + 1)
+
+ // THEN the second normal view is displayed
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title")
+ assertThat(underTest.activeViews.size).isEqualTo(1)
+ verify(configurationController, never()).removeCallback(any())
+ }
+
+ @Test
+ fun higherThenLowerPriority_lowerNotDisplayedBecauseTimedOut() {
+ underTest.displayView(
+ ViewInfo(
+ name = "critical",
+ windowTitle = "Critical Window Title",
+ id = "critical",
+ priority = ViewPriority.CRITICAL,
+ timeoutMs = 3000,
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Critical Window Title")
+ reset(windowManager)
+
+ underTest.displayView(
+ ViewInfo(
+ name = "normal",
+ windowTitle = "Normal Window Title",
+ id = "normal",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 200,
+ )
+ )
+
+ verify(windowManager, never()).removeView(viewCaptor.value)
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+ reset(windowManager)
+
+ // WHEN the first critical view has timed out
+ fakeClock.advanceTime(3000 + 1)
+
+ // THEN the second normal view is not displayed because it's already timed out
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(underTest.activeViews).isEmpty()
+ verify(configurationController).removeCallback(any())
+ }
+
+ @Test
+ fun criticalThenNewCritical_newCriticalDisplayed() {
+ underTest.displayView(
+ ViewInfo(
+ name = "critical 1",
+ windowTitle = "Critical Window Title 1",
+ id = "critical1",
+ priority = ViewPriority.CRITICAL,
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Critical Window Title 1")
+ reset(windowManager)
+
+ underTest.displayView(
+ ViewInfo(
+ name = "critical 2",
+ windowTitle = "Critical Window Title 2",
+ id = "critical2",
+ priority = ViewPriority.CRITICAL,
+ )
+ )
+
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Critical Window Title 2")
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+ verify(configurationController, never()).removeCallback(any())
+ }
+
+ @Test
+ fun normalThenNewNormal_newNormalDisplayed() {
+ underTest.displayView(
+ ViewInfo(
+ name = "normal 1",
+ windowTitle = "Normal Window Title 1",
+ id = "normal1",
+ priority = ViewPriority.NORMAL,
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title 1")
+ reset(windowManager)
+
+ underTest.displayView(
+ ViewInfo(
+ name = "normal 2",
+ windowTitle = "Normal Window Title 2",
+ id = "normal2",
+ priority = ViewPriority.NORMAL,
+ )
+ )
+
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title 2")
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+ verify(configurationController, never()).removeCallback(any())
+ }
+
+ @Test
+ fun lowerPriorityViewUpdatedWhileHigherPriorityDisplayed_eventuallyDisplaysUpdated() {
+ // First, display a lower priority view
+ underTest.displayView(
+ ViewInfo(
+ name = "normal",
+ windowTitle = "Normal Window Title",
+ id = "normal",
+ priority = ViewPriority.NORMAL,
+ // At the end of the test, we'll verify that this information isn't re-displayed.
+ // Use a super long timeout so that, when we verify it wasn't re-displayed, we know
+ // that it wasn't because the view just timed out.
+ timeoutMs = 100000,
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title")
+ reset(windowManager)
+
+ // Then, display a higher priority view
+ fakeClock.advanceTime(1000)
+ underTest.displayView(
+ ViewInfo(
+ name = "critical",
+ windowTitle = "Critical Window Title",
+ id = "critical",
+ priority = ViewPriority.CRITICAL,
+ timeoutMs = 3000,
+ )
+ )
+
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Critical Window Title")
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+ reset(windowManager)
+
+ // While the higher priority view is displayed, update the lower priority view with new
+ // information
+ fakeClock.advanceTime(1000)
+ val updatedViewInfo = ViewInfo(
+ name = "normal with update",
+ windowTitle = "Normal Window Title",
+ id = "normal",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 4000,
+ )
+ underTest.displayView(updatedViewInfo)
+
+ verify(windowManager, never()).removeView(viewCaptor.value)
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+ reset(windowManager)
+
+ // WHEN the higher priority view times out
+ fakeClock.advanceTime(2001)
+
+ // THEN the higher priority view disappears and the lower priority view *with the updated
+ // information* gets displayed.
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Normal Window Title")
+ assertThat(underTest.activeViews.size).isEqualTo(1)
+ assertThat(underTest.mostRecentViewInfo).isEqualTo(updatedViewInfo)
+ reset(windowManager)
+
+ // WHEN the updated view times out
+ fakeClock.advanceTime(2001)
+
+ // THEN the old information is never displayed
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(underTest.activeViews.size).isEqualTo(0)
+ }
+
+ @Test
+ fun oldViewUpdatedWhileNewViewDisplayed_eventuallyDisplaysUpdated() {
+ // First, display id1 view
+ underTest.displayView(
+ ViewInfo(
+ name = "name 1",
+ windowTitle = "Name 1 Title",
+ id = "id1",
+ priority = ViewPriority.NORMAL,
+ // At the end of the test, we'll verify that this information isn't re-displayed.
+ // Use a super long timeout so that, when we verify it wasn't re-displayed, we know
+ // that it wasn't because the view just timed out.
+ timeoutMs = 100000,
+ )
+ )
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Name 1 Title")
+ reset(windowManager)
+
+ // Then, display a new id2 view
+ fakeClock.advanceTime(1000)
+ underTest.displayView(
+ ViewInfo(
+ name = "name 2",
+ windowTitle = "Name 2 Title",
+ id = "id2",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 3000,
+ )
+ )
+
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Name 2 Title")
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+ reset(windowManager)
+
+ // While the id2 view is displayed, re-display the id1 view with new information
+ fakeClock.advanceTime(1000)
+ val updatedViewInfo = ViewInfo(
+ name = "name 1 with update",
+ windowTitle = "Name 1 Title",
+ id = "id1",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 3000,
+ )
+ underTest.displayView(updatedViewInfo)
+
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Name 1 Title")
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+ reset(windowManager)
+
+ // WHEN the id1 view with new information times out
+ fakeClock.advanceTime(3001)
+
+ // THEN the id1 view disappears and the old id1 information is never displayed
+ verify(windowManager).removeView(viewCaptor.value)
+ verify(windowManager, never()).addView(any(), any())
+ assertThat(underTest.activeViews.size).isEqualTo(0)
+ }
+
+ @Test
+ fun oldViewUpdatedWhileNewViewDisplayed_usesNewTimeout() {
+ // First, display id1 view
+ underTest.displayView(
+ ViewInfo(
+ name = "name 1",
+ windowTitle = "Name 1 Title",
+ id = "id1",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 5000,
+ )
+ )
+
+ // Then, display a new id2 view
+ fakeClock.advanceTime(1000)
+ underTest.displayView(
+ ViewInfo(
+ name = "name 2",
+ windowTitle = "Name 2 Title",
+ id = "id2",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 3000,
+ )
+ )
+ reset(windowManager)
+
+ // While the id2 view is displayed, re-display the id1 view with new information *and a
+ // longer timeout*
+ fakeClock.advanceTime(1000)
+ val updatedViewInfo = ViewInfo(
+ name = "name 1 with update",
+ windowTitle = "Name 1 Title",
+ id = "id1",
+ priority = ViewPriority.NORMAL,
+ timeoutMs = 30000,
+ )
+ underTest.displayView(updatedViewInfo)
+
+ val viewCaptor = argumentCaptor<View>()
+ val windowParamsCaptor = argumentCaptor<WindowManager.LayoutParams>()
+ verify(windowManager).addView(capture(viewCaptor), capture(windowParamsCaptor))
+ assertThat(windowParamsCaptor.value.title).isEqualTo("Name 1 Title")
+ assertThat(underTest.activeViews.size).isEqualTo(2)
+ reset(windowManager)
+
+ // WHEN id1's *old* timeout occurs
+ fakeClock.advanceTime(3001)
+
+ // THEN id1 is still displayed because it was updated with a new timeout
+ verify(windowManager, never()).removeView(viewCaptor.value)
+ assertThat(underTest.activeViews.size).isEqualTo(1)
}
@Test
@@ -395,6 +968,7 @@
verify(windowManager).removeView(any())
verify(logger).logViewRemoval(deviceId, reason)
+ verify(configurationController).removeCallback(any())
}
@Test
@@ -414,23 +988,27 @@
inner class TestController(
context: Context,
- logger: TemporaryViewLogger,
+ logger: TemporaryViewLogger<ViewInfo>,
windowManager: WindowManager,
@Main mainExecutor: DelayableExecutor,
accessibilityManager: AccessibilityManager,
configurationController: ConfigurationController,
+ dumpManager: DumpManager,
powerManager: PowerManager,
wakeLockBuilder: WakeLock.Builder,
- ) : TemporaryViewDisplayController<ViewInfo, TemporaryViewLogger>(
+ systemClock: SystemClock,
+ ) : TemporaryViewDisplayController<ViewInfo, TemporaryViewLogger<ViewInfo>>(
context,
logger,
windowManager,
mainExecutor,
accessibilityManager,
configurationController,
+ dumpManager,
powerManager,
R.layout.chipbar,
wakeLockBuilder,
+ systemClock,
) {
var mostRecentViewInfo: ViewInfo? = null
@@ -447,12 +1025,13 @@
override fun start() {}
}
- inner class ViewInfo(
+ data class ViewInfo(
val name: String,
override val windowTitle: String = "Window Title",
override val wakeReason: String = "WAKE_REASON",
- override val timeoutMs: Int = 1,
+ override val timeoutMs: Int = TIMEOUT_MS.toInt(),
override val id: String = "id",
+ override val priority: ViewPriority = ViewPriority.NORMAL,
) : TemporaryViewInfo()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
index 116b8fe..2e66b20 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
@@ -32,7 +32,7 @@
@SmallTest
class TemporaryViewLoggerTest : SysuiTestCase() {
private lateinit var buffer: LogBuffer
- private lateinit var logger: TemporaryViewLogger
+ private lateinit var logger: TemporaryViewLogger<TemporaryViewInfo>
@Before
fun setUp() {
@@ -44,13 +44,22 @@
@Test
fun logViewAddition_bufferHasLog() {
- logger.logViewAddition("test id", "Test Window Title")
+ val info =
+ object : TemporaryViewInfo() {
+ override val id: String = "test id"
+ override val priority: ViewPriority = ViewPriority.CRITICAL
+ override val windowTitle: String = "Test Window Title"
+ override val wakeReason: String = "wake reason"
+ }
+
+ logger.logViewAddition(info)
val stringWriter = StringWriter()
buffer.dump(PrintWriter(stringWriter), tailLength = 0)
val actualString = stringWriter.toString()
assertThat(actualString).contains(TAG)
+ assertThat(actualString).contains("test id")
assertThat(actualString).contains("Test Window Title")
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
index 7014f93..d3411c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
@@ -36,9 +36,11 @@
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
import com.android.systemui.common.shared.model.TintedIcon
+import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.temporarydisplay.ViewPriority
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
@@ -65,6 +67,7 @@
@Mock private lateinit var logger: ChipbarLogger
@Mock private lateinit var accessibilityManager: AccessibilityManager
@Mock private lateinit var configurationController: ConfigurationController
+ @Mock private lateinit var dumpManager: DumpManager
@Mock private lateinit var powerManager: PowerManager
@Mock private lateinit var windowManager: WindowManager
@Mock private lateinit var falsingManager: FalsingManager
@@ -99,12 +102,14 @@
fakeExecutor,
accessibilityManager,
configurationController,
+ dumpManager,
powerManager,
falsingManager,
falsingCollector,
viewUtil,
vibratorHelper,
fakeWakeLockBuilder,
+ fakeClock,
)
underTest.start()
}
@@ -408,6 +413,7 @@
wakeReason = WAKE_REASON,
timeoutMs = TIMEOUT,
id = DEVICE_ID,
+ priority = ViewPriority.NORMAL,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt
index beedf9f..b9a5bd7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt
@@ -22,10 +22,12 @@
import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.view.ViewUtil
import com.android.systemui.util.wakelock.WakeLock
@@ -37,12 +39,14 @@
mainExecutor: DelayableExecutor,
accessibilityManager: AccessibilityManager,
configurationController: ConfigurationController,
+ dumpManager: DumpManager,
powerManager: PowerManager,
falsingManager: FalsingManager,
falsingCollector: FalsingCollector,
viewUtil: ViewUtil,
vibratorHelper: VibratorHelper,
wakeLockBuilder: WakeLock.Builder,
+ systemClock: SystemClock,
) :
ChipbarCoordinator(
context,
@@ -51,12 +55,14 @@
mainExecutor,
accessibilityManager,
configurationController,
+ dumpManager,
powerManager,
falsingManager,
falsingCollector,
viewUtil,
vibratorHelper,
wakeLockBuilder,
+ systemClock,
) {
override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) {
// Just bypass the animation in tests
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
index 4e2736c7..c7dc0ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
@@ -18,6 +18,7 @@
import android.hardware.devicestate.DeviceStateManager
import android.hardware.devicestate.DeviceStateManager.FoldStateListener
+import android.provider.Settings
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.util.LatencyTracker
@@ -32,9 +33,11 @@
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
+import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
+import java.util.Optional
@RunWith(AndroidTestingRunner::class)
@SmallTest
@@ -59,14 +62,18 @@
private lateinit var unfoldLatencyTracker: UnfoldLatencyTracker
+ private val transitionProgressProvider = TestUnfoldTransitionProvider()
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
unfoldLatencyTracker = UnfoldLatencyTracker(
latencyTracker,
deviceStateManager,
+ Optional.of(transitionProgressProvider),
context.mainExecutor,
context,
+ context.contentResolver,
screenLifecycle
).apply { init() }
deviceStates = FoldableTestUtils.findDeviceStates(context)
@@ -76,8 +83,11 @@
}
@Test
- fun unfold_eventPropagated() {
+ fun unfold_startedFolded_animationsDisabled_eventPropagatedOnScreenTurnedOnEvent() {
+ setAnimationsEnabled(false)
+ sendFoldEvent(folded = true)
sendFoldEvent(folded = false)
+
sendScreenTurnedOnEvent()
verify(latencyTracker).onActionStart(any())
@@ -85,14 +95,77 @@
}
@Test
- fun fold_eventNotPropagated() {
+ fun unfold_startedFolded_animationsEnabledOnScreenTurnedOn_eventNotFinished() {
+ setAnimationsEnabled(true)
sendFoldEvent(folded = true)
+ sendFoldEvent(folded = false)
+
+ sendScreenTurnedOnEvent()
+
+ verify(latencyTracker).onActionStart(any())
+ verify(latencyTracker, never()).onActionEnd(any())
+ }
+
+ @Test
+ fun unfold_firstFoldEventAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventNotPropagated() {
+ setAnimationsEnabled(true)
+ sendFoldEvent(folded = false)
+
+ sendScreenTurnedOnEvent()
+ transitionProgressProvider.onTransitionStarted()
+
+ verifyNoMoreInteractions(latencyTracker)
+ }
+
+ @Test
+ fun unfold_secondFoldEventAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventPropagated() {
+ setAnimationsEnabled(true)
+ sendFoldEvent(folded = true)
+ sendFoldEvent(folded = false)
+
+ sendScreenTurnedOnEvent()
+ transitionProgressProvider.onTransitionStarted()
+
+ verify(latencyTracker).onActionStart(any())
+ verify(latencyTracker).onActionEnd(any())
+ }
+
+ @Test
+ fun unfold_unfoldFoldUnfoldAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventPropagated() {
+ setAnimationsEnabled(true)
+ sendFoldEvent(folded = false)
+ sendFoldEvent(folded = true)
+ sendFoldEvent(folded = false)
+
+ sendScreenTurnedOnEvent()
+ transitionProgressProvider.onTransitionStarted()
+
+ verify(latencyTracker).onActionStart(any())
+ verify(latencyTracker).onActionEnd(any())
+ }
+
+ @Test
+ fun fold_animationsDisabled_screenTurnedOn_eventNotPropagated() {
+ setAnimationsEnabled(false)
+ sendFoldEvent(folded = true)
+
sendScreenTurnedOnEvent() // outer display on.
verifyNoMoreInteractions(latencyTracker)
}
@Test
+ fun fold_animationsEnabled_screenTurnedOn_eventNotPropagated() {
+ setAnimationsEnabled(true)
+ sendFoldEvent(folded = true)
+
+ sendScreenTurnedOnEvent() // outer display on.
+ transitionProgressProvider.onTransitionStarted()
+
+ verifyNoMoreInteractions(latencyTracker)
+ }
+
+ @Test
fun onScreenTurnedOn_stateNeverSet_eventNotPropagated() {
sendScreenTurnedOnEvent()
@@ -107,4 +180,20 @@
private fun sendScreenTurnedOnEvent() {
screenLifecycleCaptor.value.onScreenTurnedOn()
}
+
+ private fun setAnimationsEnabled(enabled: Boolean) {
+ val durationScale =
+ if (enabled) {
+ 1f
+ } else {
+ 0f
+ }
+
+ // It uses [TestableSettingsProvider] and it will be cleared after the test
+ Settings.Global.putString(
+ context.contentResolver,
+ Settings.Global.ANIMATOR_DURATION_SCALE,
+ durationScale.toString()
+ )
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index b9dfc27..2e06cc5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -77,7 +77,6 @@
import android.view.ViewTreeObserver;
import android.view.WindowManager;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.internal.colorextraction.ColorExtractor;
@@ -142,6 +141,7 @@
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
+import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -152,13 +152,13 @@
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
-@FlakyTest
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -411,6 +411,15 @@
.addCallback(mKeyguardStateControllerCallbackCaptor.capture());
}
+ @After
+ public void tearDown() {
+ ArrayList<Bubble> bubbles = new ArrayList<>(mBubbleData.getBubbles());
+ for (int i = 0; i < bubbles.size(); i++) {
+ mBubbleController.removeBubble(bubbles.get(i).getKey(),
+ Bubbles.DISMISS_NO_LONGER_BUBBLE);
+ }
+ }
+
@Test
public void dreamingHidesBubbles() throws RemoteException {
mBubbleController.updateBubble(mBubbleEntry);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 5c2a915..5501949 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -120,6 +120,14 @@
_dozeAmount.value = dozeAmount
}
+ fun setWakefulnessModel(model: WakefulnessModel) {
+ _wakefulnessModel.value = model
+ }
+
+ fun setBouncerShowing(isShowing: Boolean) {
+ _isBouncerShowing.value = isShowing
+ }
+
fun setBiometricUnlockState(state: BiometricUnlockModel) {
_biometricUnlockState.tryEmit(state)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
new file mode 100644
index 0000000..2c0a8fd
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.shade.data.repository
+
+import com.android.systemui.shade.domain.model.ShadeModel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+
+/** Fake implementation of [KeyguardRepository] */
+class FakeShadeRepository : ShadeRepository {
+
+ private val _shadeModel = MutableStateFlow(ShadeModel())
+ override val shadeModel: Flow<ShadeModel> = _shadeModel
+
+ fun setShadeModel(model: ShadeModel) {
+ _shadeModel.value = model
+ }
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
index ecc029d..074b1e1 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
@@ -16,6 +16,7 @@
package com.android.systemui.unfold.progress
import android.os.Trace
+import android.os.Trace.TRACE_TAG_APP
import android.util.Log
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.FloatPropertyCompat
@@ -157,7 +158,10 @@
}
private fun onStartTransition() {
+ Trace.beginSection( "$TAG#onStartTransition")
listeners.forEach { it.onTransitionStarted() }
+ Trace.endSection()
+
isTransitionRunning = true
if (DEBUG) {
diff --git a/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml b/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml
index a1075d2..01bd4df 100644
--- a/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml
+++ b/packages/VpnDialogs/res/values-b+sr+Latn/strings.xml
@@ -16,22 +16,22 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="prompt" msgid="3183836924226407828">"Zahtev za povezivanje"</string>
- <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> želi da podesi VPN vezu koja omogućava praćenje saobraćaja na mreži. Prihvatite samo ako verujete izvoru. <br /> <br /> <img src=vpn_icon /> se prikazuje u vrhu ekrana kada je VPN aktivan."</string>
- <string name="warning" product="tv" msgid="5188957997628124947">"Aplikacija <xliff:g id="APP">%s</xliff:g> želi da podesi VPN vezu koja joj omogućava da prati mrežni saobraćaj. Prihvatite ovo samo ako imate poverenja u izvor. <br /> <br /> <img src=vpn_icon /> se prikazuje na ekranu kada je VPN aktivan."</string>
- <string name="legacy_title" msgid="192936250066580964">"VPN je povezan"</string>
- <string name="session" msgid="6470628549473641030">"Sesija:"</string>
- <string name="duration" msgid="3584782459928719435">"Trajanje:"</string>
- <string name="data_transmitted" msgid="7988167672982199061">"Poslato:"</string>
- <string name="data_received" msgid="4062776929376067820">"Primljeno:"</string>
- <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bajt(ov)a / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketa"</string>
- <string name="always_on_disconnected_title" msgid="1906740176262776166">"Povezivanje sa uvek uključenim VPN-om nije uspelo"</string>
- <string name="always_on_disconnected_message" msgid="555634519845992917">"Mreža <xliff:g id="VPN_APP_0">%1$s</xliff:g> je podešena da bude uvek povezana, ali trenutno ne može da uspostavi vezu. Telefon će koristiti javnu mrežu dok se ponovo ne poveže sa <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
- <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Mreža <xliff:g id="VPN_APP">%1$s</xliff:g> je podešena da bude uvek povezana, ali trenutno ne može da uspostavi vezu. Nećete imati vezu dok se VPN ponovo ne poveže."</string>
+ <string name="prompt" msgid="3183836924226407828">"Захтев за повезивање"</string>
+ <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> жели да подеси VPN везу која омогућава праћење саобраћаја на мрежи. Прихватите само ако верујете извору. <br /> <br /> <img src=vpn_icon /> се приказује у врху екрана када је VPN активан."</string>
+ <string name="warning" product="tv" msgid="5188957997628124947">"Апликација <xliff:g id="APP">%s</xliff:g> жели да подеси VPN везу која јој омогућава да прати мрежни саобраћај. Прихватите ово само ако имате поверења у извор. <br /> <br /> <img src=vpn_icon /> се приказује на екрану када је VPN активан."</string>
+ <string name="legacy_title" msgid="192936250066580964">"VPN је повезан"</string>
+ <string name="session" msgid="6470628549473641030">"Сесија:"</string>
+ <string name="duration" msgid="3584782459928719435">"Трајање:"</string>
+ <string name="data_transmitted" msgid="7988167672982199061">"Послато:"</string>
+ <string name="data_received" msgid="4062776929376067820">"Примљенo:"</string>
+ <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> бајт(ов)а / <xliff:g id="NUMBER_1">%2$s</xliff:g> пакета"</string>
+ <string name="always_on_disconnected_title" msgid="1906740176262776166">"Повезивање са увек укљученим VPN-ом није успело"</string>
+ <string name="always_on_disconnected_message" msgid="555634519845992917">"Мрежа <xliff:g id="VPN_APP_0">%1$s</xliff:g> је подешена да буде увек повезана, али тренутно не може да успостави везу. Телефон ће користити јавну мрежу док се поново не повеже са <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
+ <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Мрежа <xliff:g id="VPN_APP">%1$s</xliff:g> је подешена да буде увек повезана, али тренутно не може да успостави везу. Нећете имати везу док се VPN поново не повеже."</string>
<string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
- <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Promeni podešavanja VPN-a"</string>
- <string name="configure" msgid="4905518375574791375">"Konfiguriši"</string>
- <string name="disconnect" msgid="971412338304200056">"Prekini vezu"</string>
- <string name="open_app" msgid="3717639178595958667">"Otvori aplikaciju"</string>
- <string name="dismiss" msgid="6192859333764711227">"Odbaci"</string>
+ <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Промени подешавања VPN-а"</string>
+ <string name="configure" msgid="4905518375574791375">"Конфигуриши"</string>
+ <string name="disconnect" msgid="971412338304200056">"Прекини везу"</string>
+ <string name="open_app" msgid="3717639178595958667">"Отвори апликацију"</string>
+ <string name="dismiss" msgid="6192859333764711227">"Одбаци"</string>
</resources>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-b+sr+Latn/strings.xml
index f80fa8d..c2b611e 100644
--- a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"Prikazuj aplikacije ispod oblasti izreza"</string>
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"Приказуј апликације испод области изреза"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-b+sr+Latn/strings.xml
index 5393410..0adf1dd 100644
--- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"Izrezana slika u uglu ekrana"</string>
+ <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"Изрезана слика у углу екрана"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-b+sr+Latn/strings.xml
index d2eb7db..99b89a2 100644
--- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"Izrezana slika za duple ekrane"</string>
+ <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"Изрезана слика за дупле екране"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-b+sr+Latn/strings.xml
index 97d544c..411ab7a 100644
--- a/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="7305489596221077240">"Izrezana slika u obliku rupe"</string>
+ <string name="display_cutout_emulation_overlay" msgid="7305489596221077240">"Изрезана слика у облику рупе"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-b+sr+Latn/strings.xml
index d78d344..9026c36 100644
--- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-b+sr+Latn/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="3947428012427075896">"Izrezana slika za uske ekrane"</string>
+ <string name="display_cutout_emulation_overlay" msgid="3947428012427075896">"Изрезана слика за уске екране"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-b+sr+Latn/strings.xml
index 46d30c6..8ee39b8 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"Izrezana slika za visoke ekrane"</string>
+ <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"Изрезана слика за високе екране"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-b+sr+Latn/strings.xml
index 4cb324c..24e3828 100644
--- a/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="3523556473422419323">"Izrezani slap"</string>
+ <string name="display_cutout_emulation_overlay" msgid="3523556473422419323">"Изрезани слап"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-b+sr+Latn/strings.xml
index d4160f4..6087dd7 100644
--- a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="4043478945358357737">"Izrezana slika za široke ekrane"</string>
+ <string name="display_cutout_emulation_overlay" msgid="4043478945358357737">"Изрезана слика за широке екране"</string>
</resources>
diff --git a/packages/overlays/NoCutoutOverlay/res/values-b+sr+Latn/strings.xml b/packages/overlays/NoCutoutOverlay/res/values-b+sr+Latn/strings.xml
index 082e586..26afbf9 100644
--- a/packages/overlays/NoCutoutOverlay/res/values-b+sr+Latn/strings.xml
+++ b/packages/overlays/NoCutoutOverlay/res/values-b+sr+Latn/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"Sakrij"</string>
+ <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"Сакриј"</string>
</resources>
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index 6bb19ce..5f1da7b 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -201,6 +201,30 @@
});
}
+ public void maybeSetFillRequestSentTimestampMs(int timestamp) {
+ mEventInternal.ifPresent(event -> {
+ event.mFillRequestSentTimestampMs = timestamp;
+ });
+ }
+
+ public void maybeSetFillResponseReceivedTimestampMs(int timestamp) {
+ mEventInternal.ifPresent(event -> {
+ event.mFillResponseReceivedTimestampMs = timestamp;
+ });
+ }
+
+ public void maybeSetSuggestionSentTimestampMs(int timestamp) {
+ mEventInternal.ifPresent(event -> {
+ event.mSuggestionSentTimestampMs = timestamp;
+ });
+ }
+
+ public void maybeSetSuggestionPresentedTimestampMs(int timestamp) {
+ mEventInternal.ifPresent(event -> {
+ event.mSuggestionPresentedTimestampMs = timestamp;
+ });
+ }
+
public void maybeSetInlinePresentationAndSuggestionHostUid(Context context, int userId) {
mEventInternal.ifPresent(event -> {
event.mDisplayPresentationType =
@@ -262,7 +286,11 @@
+ " mDisplayPresentationType=" + event.mDisplayPresentationType
+ " mAutofillServiceUid=" + event.mAutofillServiceUid
+ " mInlineSuggestionHostUid=" + event.mInlineSuggestionHostUid
- + " mIsRequestTriggered=" + event.mIsRequestTriggered);
+ + " mIsRequestTriggered=" + event.mIsRequestTriggered
+ + " mFillRequestSentTimestampMs=" + event.mFillRequestSentTimestampMs
+ + " mFillResponseReceivedTimestampMs=" + event.mFillResponseReceivedTimestampMs
+ + " mSuggestionSentTimestampMs=" + event.mSuggestionSentTimestampMs
+ + " mSuggestionPresentedTimestampMs=" + event.mSuggestionPresentedTimestampMs);
}
// TODO(b/234185326): Distinguish empty responses from other no presentation reasons.
@@ -283,7 +311,11 @@
event.mDisplayPresentationType,
event.mAutofillServiceUid,
event.mInlineSuggestionHostUid,
- event.mIsRequestTriggered);
+ event.mIsRequestTriggered,
+ event.mFillRequestSentTimestampMs,
+ event.mFillResponseReceivedTimestampMs,
+ event.mSuggestionSentTimestampMs,
+ event.mSuggestionPresentedTimestampMs);
mEventInternal = Optional.empty();
}
@@ -300,6 +332,10 @@
int mAutofillServiceUid = -1;
int mInlineSuggestionHostUid = -1;
boolean mIsRequestTriggered;
+ int mFillRequestSentTimestampMs;
+ int mFillResponseReceivedTimestampMs;
+ int mSuggestionSentTimestampMs;
+ int mSuggestionPresentedTimestampMs;
PresentationStatsEventInternal() {}
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 5c11e2c..a706b0d 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -24,6 +24,7 @@
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_UNKNOWN;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
+import static android.service.autofill.FillRequest.FLAG_RESET_FILL_DIALOG_STATE;
import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG;
import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED;
import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
@@ -321,6 +322,13 @@
private final long mStartTime;
/**
+ * Starting timestamp of latency logger.
+ * This is set when Session created or when the view is reset.
+ */
+ @GuardedBy("mLock")
+ private long mLatencyBaseTime;
+
+ /**
* When the UI was shown for the first time (using elapsed time since boot).
*/
@GuardedBy("mLock")
@@ -411,6 +419,14 @@
@GuardedBy("mLock")
private boolean mStartedLogEventWithoutFocus;
+ /**
+ * Keeps the fill dialog trigger ids of the last response. This invalidates
+ * the trigger ids of the previous response.
+ */
+ @Nullable
+ @GuardedBy("mLock")
+ private AutofillId[] mLastFillDialogTriggerIds;
+
void onSwitchInputMethodLocked() {
// One caveat is that for the case where the focus is on a field for which regular autofill
// returns null, and augmented autofill is triggered, and then the user switches the input
@@ -984,6 +1000,11 @@
mAssistReceiver.newAutofillRequestLocked(viewState, /* isInlineRequest= */ false);
}
+ final long fillRequestSentRelativeTimestamp =
+ SystemClock.elapsedRealtime() - mLatencyBaseTime;
+ mPresentationStatsEventLogger.maybeSetFillRequestSentTimestampMs(
+ (int) (fillRequestSentRelativeTimestamp));
+
// Now request the assist structure data.
requestAssistStructureLocked(requestId, flags);
}
@@ -1028,6 +1049,7 @@
this.taskId = taskId;
this.uid = uid;
mStartTime = SystemClock.elapsedRealtime();
+ mLatencyBaseTime = mStartTime;
mService = service;
mLock = lock;
mUi = ui;
@@ -1057,6 +1079,14 @@
@Override
public void notifyInlineUiShown(AutofillId autofillId) {
notifyFillUiShown(autofillId);
+
+ synchronized (mLock) {
+ // TODO(b/262448552): Log when chip inflates instead of here
+ final long inlineUiShownRelativeTimestamp =
+ SystemClock.elapsedRealtime() - mLatencyBaseTime;
+ mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs(
+ (int) (inlineUiShownRelativeTimestamp));
+ }
}
@Override
@@ -1150,6 +1180,12 @@
return;
}
+ // Time passed since session was created
+ final long fillRequestReceivedRelativeTimestamp =
+ SystemClock.elapsedRealtime() - mLatencyBaseTime;
+ mPresentationStatsEventLogger.maybeSetFillResponseReceivedTimestampMs(
+ (int) (fillRequestReceivedRelativeTimestamp));
+
requestLog = mRequestLogs.get(requestId);
if (requestLog != null) {
requestLog.setType(MetricsEvent.TYPE_SUCCESS);
@@ -1171,6 +1207,8 @@
return;
}
+ mLastFillDialogTriggerIds = response.getFillDialogTriggerIds();
+
final int flags = response.getFlags();
if ((flags & FillResponse.FLAG_DELAY_FILL) != 0) {
Slog.v(TAG, "Service requested to wait for delayed fill response.");
@@ -1277,6 +1315,7 @@
+ (timedOut ? "timeout" : "failure"));
}
mService.resetLastResponse();
+ mLastFillDialogTriggerIds = null;
final LogMaker requestLog = mRequestLogs.get(requestId);
if (requestLog == null) {
Slog.w(TAG, "onFillRequestFailureOrTimeout(): no log for id " + requestId);
@@ -2973,6 +3012,11 @@
}
}
+ if ((flags & FLAG_RESET_FILL_DIALOG_STATE) != 0) {
+ if (sDebug) Log.d(TAG, "force to reset fill dialog state");
+ mSessionFlags.mFillDialogDisabled = false;
+ }
+
switch(action) {
case ACTION_START_SESSION:
// View is triggering autofill.
@@ -3035,6 +3079,8 @@
case ACTION_VIEW_ENTERED:
boolean startedEventWithoutFocus = mStartedLogEventWithoutFocus;
mStartedLogEventWithoutFocus = false;
+ mLatencyBaseTime = SystemClock.elapsedRealtime();
+
if (sVerbose && virtualBounds != null) {
Slog.v(TAG, "entered on virtual child " + id + ": " + virtualBounds);
}
@@ -3301,6 +3347,14 @@
return;
}
+ synchronized (mLock) {
+ // Time passed since Session was created
+ long suggestionSentRelativeTimestamp =
+ SystemClock.elapsedRealtime() - mLatencyBaseTime;
+ mPresentationStatsEventLogger.maybeSetSuggestionSentTimestampMs(
+ (int) (suggestionSentRelativeTimestamp));
+ }
+
final AutofillId[] ids = response.getFillDialogTriggerIds();
if (ids != null && ArrayUtils.contains(ids, filledId)) {
if (requestShowFillDialog(response, filledId, filterText, flags)) {
@@ -3317,6 +3371,13 @@
// Note: Cannot disable before requestShowFillDialog() because the method
// need to check whether fill dialog enabled.
setFillDialogDisabled();
+ synchronized (mLock) {
+ // Logs when fill dialog ui is shown; time since Session was created
+ final long fillDialogUiShownRelativeTimestamp =
+ SystemClock.elapsedRealtime() - mLatencyBaseTime;
+ mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs(
+ (int) (fillDialogUiShownRelativeTimestamp));
+ }
return;
} else {
setFillDialogDisabled();
@@ -3327,6 +3388,8 @@
if (response.supportsInlineSuggestions()) {
synchronized (mLock) {
if (requestShowInlineSuggestionsLocked(response, filterText)) {
+ // Cannot tell for sure that InlineSuggestions are shown yet, IME needs to send
+ // back a response via callback.
final ViewState currentView = mViewStates.get(mCurrentViewId);
currentView.setState(ViewState.STATE_INLINE_SHOWN);
// TODO(b/248378401): Fix it to log showed only when IME asks for inflation,
@@ -3360,6 +3423,11 @@
// Log first time UI is shown.
mUiShownTime = SystemClock.elapsedRealtime();
final long duration = mUiShownTime - mStartTime;
+ // This logs when dropdown ui was shown. Timestamp is relative to
+ // when the session was created
+ mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs(
+ (int) (mUiShownTime - mLatencyBaseTime));
+
if (sDebug) {
final StringBuilder msg = new StringBuilder("1st UI for ")
.append(mActivityToken)
@@ -3402,10 +3470,8 @@
}
private boolean isFillDialogUiEnabled() {
- // TODO read from Settings or somewhere
- final boolean isSettingsEnabledFillDialog = true;
synchronized (mLock) {
- return isSettingsEnabledFillDialog && !mSessionFlags.mFillDialogDisabled;
+ return !mSessionFlags.mFillDialogDisabled;
}
}
@@ -3431,14 +3497,25 @@
AutofillId filledId, String filterText, int flags) {
if (!isFillDialogUiEnabled()) {
// Unsupported fill dialog UI
+ if (sDebug) Log.w(TAG, "requestShowFillDialog: fill dialog is disabled");
return false;
}
if ((flags & FillRequest.FLAG_IME_SHOWING) != 0) {
// IME is showing, fallback to normal suggestions UI
+ if (sDebug) Log.w(TAG, "requestShowFillDialog: IME is showing");
return false;
}
+ synchronized (mLock) {
+ if (mLastFillDialogTriggerIds == null
+ || !ArrayUtils.contains(mLastFillDialogTriggerIds, filledId)) {
+ // Last fill dialog triggered ids are changed.
+ if (sDebug) Log.w(TAG, "Last fill dialog triggered ids are changed.");
+ return false;
+ }
+ }
+
final Drawable serviceIcon = getServiceIcon();
getUiForShowing().showFillDialog(filledId, response, filterText,
@@ -4278,6 +4355,13 @@
if (mSessionFlags.mAugmentedAutofillOnly) {
pw.print(prefix); pw.println("For Augmented Autofill Only");
}
+ if (mSessionFlags.mFillDialogDisabled) {
+ pw.print(prefix); pw.println("Fill Dialog disabled");
+ }
+ if (mLastFillDialogTriggerIds != null) {
+ pw.print(prefix); pw.println("Last Fill Dialog trigger ids: ");
+ pw.println(mSelectedDatasetIds);
+ }
if (mAugmentedAutofillDestroyer != null) {
pw.print(prefix); pw.println("has mAugmentedAutofillDestroyer");
}
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index e529010..daba4c0 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -79,7 +79,7 @@
* completed faster than this, we assume it's not performed by human and the
* event gets ignored.
*/
- @VisibleForTesting static final int EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS = 160;
+ @VisibleForTesting static final int EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS = 200;
/**
* Interval in milliseconds in which the power button must be depressed in succession to be
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
index bea0f4f..846c2d9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
@@ -417,7 +417,7 @@
}
@Override
- public void onTrustChanged(boolean enabled, int userId, int flags,
+ public void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId, int flags,
List<String> trustGrantedMessages) {
mUserHasTrust.put(userId, enabled);
}
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index c0e7ab8..8b579ac 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -249,7 +249,7 @@
HysteresisLevels screenBrightnessThresholdsIdle, Context context,
HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
- int ambientLightHorizonLong) {
+ int ambientLightHorizonLong, float userLux, float userBrightness) {
this(new Injector(), callbacks, looper, sensorManager, lightSensor,
interactiveModeBrightnessMapper,
lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor,
@@ -258,7 +258,7 @@
ambientBrightnessThresholds, screenBrightnessThresholds,
ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, context,
hbmController, brightnessThrottler, idleModeBrightnessMapper,
- ambientLightHorizonShort, ambientLightHorizonLong
+ ambientLightHorizonShort, ambientLightHorizonLong, userLux, userBrightness
);
}
@@ -275,7 +275,7 @@
HysteresisLevels screenBrightnessThresholdsIdle, Context context,
HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
- int ambientLightHorizonLong) {
+ int ambientLightHorizonLong, float userLux, float userBrightness) {
mInjector = injector;
mClock = injector.createClock();
mContext = context;
@@ -322,6 +322,12 @@
mIdleModeBrightnessMapper = idleModeBrightnessMapper;
// Initialize to active (normal) screen brightness mode
switchToInteractiveScreenBrightnessMode();
+
+ if (userLux != BrightnessMappingStrategy.NO_USER_LUX
+ && userBrightness != BrightnessMappingStrategy.NO_USER_BRIGHTNESS) {
+ // Use the given short-term model
+ setScreenBrightnessByUser(userLux, userBrightness);
+ }
}
/**
@@ -383,7 +389,8 @@
public void configure(int state, @Nullable BrightnessConfiguration configuration,
float brightness, boolean userChangedBrightness, float adjustment,
- boolean userChangedAutoBrightnessAdjustment, int displayPolicy) {
+ boolean userChangedAutoBrightnessAdjustment, int displayPolicy,
+ boolean shouldResetShortTermModel) {
mState = state;
mHbmController.setAutoBrightnessEnabled(mState);
// While dozing, the application processor may be suspended which will prevent us from
@@ -392,7 +399,7 @@
// and hold onto the last computed screen auto brightness. We save the dozing flag for
// debugging purposes.
boolean dozing = (displayPolicy == DisplayPowerRequest.POLICY_DOZE);
- boolean changed = setBrightnessConfiguration(configuration);
+ boolean changed = setBrightnessConfiguration(configuration, shouldResetShortTermModel);
changed |= setDisplayPolicy(displayPolicy);
if (userChangedAutoBrightnessAdjustment) {
changed |= setAutoBrightnessAdjustment(adjustment);
@@ -492,9 +499,13 @@
// and we can't use this data to add a new control point to the short-term model.
return false;
}
- mCurrentBrightnessMapper.addUserDataPoint(mAmbientLux, brightness);
+ return setScreenBrightnessByUser(mAmbientLux, brightness);
+ }
+
+ private boolean setScreenBrightnessByUser(float lux, float brightness) {
+ mCurrentBrightnessMapper.addUserDataPoint(lux, brightness);
mShortTermModelValid = true;
- mShortTermModelAnchor = mAmbientLux;
+ mShortTermModelAnchor = lux;
if (mLoggingEnabled) {
Slog.d(TAG, "ShortTermModel: anchor=" + mShortTermModelAnchor);
}
@@ -514,9 +525,10 @@
mShortTermModelValid = false;
}
- public boolean setBrightnessConfiguration(BrightnessConfiguration configuration) {
+ public boolean setBrightnessConfiguration(BrightnessConfiguration configuration,
+ boolean shouldResetShortTermModel) {
if (mInteractiveModeBrightnessMapper.setBrightnessConfiguration(configuration)) {
- if (!isInIdleMode()) {
+ if (!isInIdleMode() && shouldResetShortTermModel) {
resetShortTermModel();
}
return true;
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 25d0752..3fc50c4 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -51,6 +51,9 @@
public abstract class BrightnessMappingStrategy {
private static final String TAG = "BrightnessMappingStrategy";
+ public static final float NO_USER_LUX = -1;
+ public static final float NO_USER_BRIGHTNESS = -1;
+
private static final float LUX_GRAD_SMOOTHING = 0.25f;
private static final float MAX_GRAD = 1.0f;
private static final float SHORT_TERM_MODEL_THRESHOLD_RATIO = 0.6f;
@@ -68,6 +71,7 @@
* Creates a BrightnessMappingStrategy for active (normal) mode.
* @param resources
* @param displayDeviceConfig
+ * @param displayWhiteBalanceController
* @return the BrightnessMappingStrategy
*/
@Nullable
@@ -82,6 +86,7 @@
* Creates a BrightnessMappingStrategy for idle screen brightness mode.
* @param resources
* @param displayDeviceConfig
+ * @param displayWhiteBalanceController
* @return the BrightnessMappingStrategy
*/
@Nullable
@@ -100,6 +105,7 @@
* @param displayDeviceConfig
* @param isForIdleMode determines whether the configurations loaded are for idle screen
* brightness mode or active screen brightness mode.
+ * @param displayWhiteBalanceController
* @return the BrightnessMappingStrategy
*/
@Nullable
@@ -370,6 +376,10 @@
*/
public abstract boolean isForIdleMode();
+ abstract float getUserLux();
+
+ abstract float getUserBrightness();
+
/**
* Check if the short term model should be reset given the anchor lux the last
* brightness change was made at and the current ambient lux.
@@ -604,8 +614,8 @@
mMaxGamma = maxGamma;
mAutoBrightnessAdjustment = 0;
- mUserLux = -1;
- mUserBrightness = -1;
+ mUserLux = NO_USER_LUX;
+ mUserBrightness = NO_USER_BRIGHTNESS;
if (mLoggingEnabled) {
PLOG.start("simple mapping strategy");
}
@@ -732,6 +742,16 @@
return false;
}
+ @Override
+ float getUserLux() {
+ return mUserLux;
+ }
+
+ @Override
+ float getUserBrightness() {
+ return mUserBrightness;
+ }
+
private void computeSpline() {
Pair<float[], float[]> curve = getAdjustedCurve(mLux, mBrightness, mUserLux,
mUserBrightness, mAutoBrightnessAdjustment, mMaxGamma);
@@ -799,8 +819,8 @@
mIsForIdleMode = isForIdleMode;
mMaxGamma = maxGamma;
mAutoBrightnessAdjustment = 0;
- mUserLux = -1;
- mUserBrightness = -1;
+ mUserLux = NO_USER_LUX;
+ mUserBrightness = NO_USER_BRIGHTNESS;
mDisplayWhiteBalanceController = displayWhiteBalanceController;
mNits = nits;
@@ -972,6 +992,16 @@
return mIsForIdleMode;
}
+ @Override
+ float getUserLux() {
+ return mUserLux;
+ }
+
+ @Override
+ float getUserBrightness() {
+ return mUserBrightness;
+ }
+
/**
* Prints out the default curve and how it differs from the long-term curve
* and the current curve (in case the current curve includes short-term adjustments).
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 2be2d58..5bdfa70 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -36,16 +36,20 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.config.AutoBrightness;
+import com.android.server.display.config.BlockingZoneConfig;
import com.android.server.display.config.BrightnessThresholds;
import com.android.server.display.config.BrightnessThrottlingMap;
import com.android.server.display.config.BrightnessThrottlingPoint;
import com.android.server.display.config.Density;
+import com.android.server.display.config.DisplayBrightnessPoint;
import com.android.server.display.config.DisplayConfiguration;
import com.android.server.display.config.DisplayQuirks;
import com.android.server.display.config.HbmTiming;
import com.android.server.display.config.HighBrightnessMode;
+import com.android.server.display.config.IntegerArray;
import com.android.server.display.config.NitsMap;
import com.android.server.display.config.Point;
+import com.android.server.display.config.RefreshRateConfigs;
import com.android.server.display.config.RefreshRateRange;
import com.android.server.display.config.SdrHdrRatioMap;
import com.android.server.display.config.SdrHdrRatioPoint;
@@ -130,6 +134,35 @@
* </brightnessThrottlingMap>
* </thermalThrottling>
*
+ * <refreshRate>
+ * <lowerBlockingZoneConfigs>
+ * <defaultRefreshRate>75</defaultRefreshRate>
+ * <blockingZoneThreshold>
+ * <displayBrightnessPoint>
+ * <lux>50</lux>
+ * <nits>45.3</nits>
+ * </displayBrightnessPoint>
+ * <displayBrightnessPoint>
+ * <lux>60</lux>
+ * <nits>55.2</nits>
+ * </displayBrightnessPoint>
+ * </blockingZoneThreshold>
+ * </lowerBlockingZoneConfigs>
+ * <higherBlockingZoneConfigs>
+ * <defaultRefreshRate>90</defaultRefreshRate>
+ * <blockingZoneThreshold>
+ * <displayBrightnessPoint>
+ * <lux>500</lux>
+ * <nits>245.3</nits>
+ * </displayBrightnessPoint>
+ * <displayBrightnessPoint>
+ * <lux>600</lux>
+ * <nits>232.3</nits>
+ * </displayBrightnessPoint>
+ * </blockingZoneThreshold>
+ * </higherBlockingZoneConfigs>
+ * </refreshRate>
+ *
* <highBrightnessMode enabled="true">
* <transitionPoint>0.62</transitionPoint>
* <minimumLux>10000</minimumLux>
@@ -181,6 +214,10 @@
* <type>android.sensor.light</type>
* <name>1234 Ambient Light Sensor</name>
* </lightSensor>
+ * <screenOffBrightnessSensor>
+ * <type>com.google.sensor.binned_brightness</type>
+ * <name>Binned Brightness 0 (wake-up)</name>
+ * </screenOffBrightnessSensor>
* <proxSensor>
* <type>android.sensor.proximity</type>
* <name>1234 Proximity Sensor</name>
@@ -336,6 +373,13 @@
* </brightnessThresholdPoints>
* </darkeningThresholds>
* </displayBrightnessChangeThresholdsIdle>
+ * <screenOffBrightnessSensorValueToLux>
+ * <item>-1</item>
+ * <item>0</item>
+ * <item>5</item>
+ * <item>80</item>
+ * <item>1500</item>
+ * </screenOffBrightnessSensorValueToLux>
* </displayConfiguration>
* }
* </pre>
@@ -358,6 +402,9 @@
private static final String STABLE_ID_SUFFIX_FORMAT = "id_%d";
private static final String NO_SUFFIX_FORMAT = "%d";
private static final long STABLE_FLAG = 1L << 62;
+ private static final int DEFAULT_LOW_REFRESH_RATE = 60;
+ private static final int DEFAULT_HIGH_REFRESH_RATE = 0;
+ private static final int[] DEFAULT_BRIGHTNESS_THRESHOLDS = new int[]{};
private static final float[] DEFAULT_AMBIENT_THRESHOLD_LEVELS = new float[]{0f};
private static final float[] DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS = new float[]{100f};
@@ -393,6 +440,9 @@
// The details of the ambient light sensor associated with this display.
private final SensorData mAmbientLightSensor = new SensorData();
+ // The details of the doze brightness sensor associated with this display.
+ private final SensorData mScreenOffBrightnessSensor = new SensorData();
+
// The details of the proximity sensor associated with this display.
private final SensorData mProximitySensor = new SensorData();
@@ -488,6 +538,9 @@
private float[] mAmbientDarkeningLevelsIdle = DEFAULT_AMBIENT_THRESHOLD_LEVELS;
private float[] mAmbientDarkeningPercentagesIdle = DEFAULT_AMBIENT_DARKENING_THRESHOLDS;
+ // A mapping between screen off sensor values and lux values
+ private int[] mScreenOffBrightnessSensorValueToLux;
+
private Spline mBrightnessToBacklightSpline;
private Spline mBacklightToBrightnessSpline;
private Spline mBacklightToNitsSpline;
@@ -512,6 +565,49 @@
// This stores the raw value loaded from the config file - true if not written.
private boolean mDdcAutoBrightnessAvailable = true;
+ /**
+ * The default peak refresh rate for a given device. This value prevents the framework from
+ * using higher refresh rates, even if display modes with higher refresh rates are available
+ * from hardware composer. Only has an effect if the value is non-zero.
+ */
+ private int mDefaultHighRefreshRate = DEFAULT_HIGH_REFRESH_RATE;
+
+ /**
+ * The default refresh rate for a given device. This value sets the higher default
+ * refresh rate. If the hardware composer on the device supports display modes with
+ * a higher refresh rate than the default value specified here, the framework may use those
+ * higher refresh rate modes if an app chooses one by setting preferredDisplayModeId or calling
+ * setFrameRate(). We have historically allowed fallback to mDefaultHighRefreshRate if
+ * mDefaultLowRefreshRate is set to 0, but this is not supported anymore.
+ */
+ private int mDefaultLowRefreshRate = DEFAULT_LOW_REFRESH_RATE;
+
+ /**
+ * The display uses different gamma curves for different refresh rates. It's hard for panel
+ * vendors to tune the curves to have exact same brightness for different refresh rate. So
+ * brightness flickers could be observed at switch time. The issue is worse at the gamma lower
+ * end. In addition, human eyes are more sensitive to the flicker at darker environment. To
+ * prevent flicker, we only support higher refresh rates if the display brightness is above a
+ * threshold. For example, no higher refresh rate if display brightness <= disp0 && ambient
+ * brightness <= amb0 || display brightness <= disp1 && ambient brightness <= amb1
+ */
+ private int[] mLowDisplayBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
+ private int[] mLowAmbientBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
+
+ /**
+ * The display uses different gamma curves for different refresh rates. It's hard for panel
+ * vendors to tune the curves to have exact same brightness for different refresh rate. So
+ * brightness flickers could be observed at switch time. The issue can be observed on the screen
+ * with even full white content at the high brightness. To prevent flickering, we support fixed
+ * refresh rates if the display and ambient brightness are equal to or above the provided
+ * thresholds. You can define multiple threshold levels as higher brightness environments may
+ * have lower display brightness requirements for the flickering is visible. For example, fixed
+ * refresh rate if display brightness >= disp0 && ambient brightness >= amb0 || display
+ * brightness >= disp1 && ambient brightness >= amb1
+ */
+ private int[] mHighDisplayBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
+ private int[] mHighAmbientBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
+
// Brightness Throttling data may be updated via the DeviceConfig. Here we store the original
// data, which comes from the ddc, and the current one, which may be the DeviceConfig
// overwritten value.
@@ -1120,6 +1216,10 @@
return mAmbientLightSensor;
}
+ SensorData getScreenOffBrightnessSensor() {
+ return mScreenOffBrightnessSensor;
+ }
+
SensorData getProximitySensor() {
return mProximitySensor;
}
@@ -1196,15 +1296,15 @@
/**
* @return Default peak refresh rate of the associated display
*/
- public int getDefaultPeakRefreshRate() {
- return mContext.getResources().getInteger(R.integer.config_defaultPeakRefreshRate);
+ public int getDefaultHighRefreshRate() {
+ return mDefaultHighRefreshRate;
}
/**
* @return Default refresh rate of the associated display
*/
- public int getDefaultRefreshRate() {
- return mContext.getResources().getInteger(R.integer.config_defaultRefreshRate);
+ public int getDefaultLowRefreshRate() {
+ return mDefaultLowRefreshRate;
}
/**
@@ -1213,8 +1313,7 @@
* allowed
*/
public int[] getLowDisplayBrightnessThresholds() {
- return mContext.getResources().getIntArray(
- R.array.config_brightnessThresholdsOfPeakRefreshRate);
+ return mLowDisplayBrightnessThresholds;
}
/**
@@ -1223,8 +1322,7 @@
* allowed
*/
public int[] getLowAmbientBrightnessThresholds() {
- return mContext.getResources().getIntArray(
- R.array.config_ambientThresholdsOfPeakRefreshRate);
+ return mLowAmbientBrightnessThresholds;
}
/**
@@ -1233,8 +1331,7 @@
* allowed
*/
public int[] getHighDisplayBrightnessThresholds() {
- return mContext.getResources().getIntArray(
- R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate);
+ return mHighDisplayBrightnessThresholds;
}
/**
@@ -1243,8 +1340,15 @@
* allowed
*/
public int[] getHighAmbientBrightnessThresholds() {
- return mContext.getResources().getIntArray(
- R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate);
+ return mHighAmbientBrightnessThresholds;
+ }
+
+ /**
+ * @return A mapping from screen off brightness sensor readings to lux values. This estimates
+ * the ambient lux when the screen is off to determine the initial brightness
+ */
+ public int[] getScreenOffBrightnessSensorValueToLux() {
+ return mScreenOffBrightnessSensorValueToLux;
}
@Override
@@ -1325,6 +1429,7 @@
mScreenDarkeningPercentagesIdle)
+ "\n"
+ ", mAmbientLightSensor=" + mAmbientLightSensor
+ + ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor
+ ", mProximitySensor=" + mProximitySensor
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
+ ", mDensityMapping= " + mDensityMapping
@@ -1336,6 +1441,20 @@
+ ", mBrightnessLevelsNits= " + Arrays.toString(mBrightnessLevelsNits)
+ ", mDdcAutoBrightnessAvailable= " + mDdcAutoBrightnessAvailable
+ ", mAutoBrightnessAvailable= " + mAutoBrightnessAvailable
+ + "\n"
+ + ", mDefaultRefreshRate= " + mDefaultLowRefreshRate
+ + ", mDefaultPeakRefreshRate= " + mDefaultHighRefreshRate
+ + ", mLowDisplayBrightnessThresholds= "
+ + Arrays.toString(mLowDisplayBrightnessThresholds)
+ + ", mLowAmbientBrightnessThresholds= "
+ + Arrays.toString(mLowAmbientBrightnessThresholds)
+ + ", mHighDisplayBrightnessThresholds= "
+ + Arrays.toString(mHighDisplayBrightnessThresholds)
+ + ", mHighAmbientBrightnessThresholds= "
+ + Arrays.toString(mHighAmbientBrightnessThresholds)
+ + "\n"
+ + ", mScreenOffBrightnessSensorValueToLux=" + Arrays.toString(
+ mScreenOffBrightnessSensorValueToLux)
+ "}";
}
@@ -1389,10 +1508,13 @@
loadQuirks(config);
loadBrightnessRamps(config);
loadAmbientLightSensorFromDdc(config);
+ loadScreenOffBrightnessSensorFromDdc(config);
loadProxSensorFromDdc(config);
loadAmbientHorizonFromDdc(config);
loadBrightnessChangeThresholds(config);
loadAutoBrightnessConfigValues(config);
+ loadRefreshRateSetting(config);
+ loadScreenOffBrightnessSensorValueToLuxFromDdc(config);
} else {
Slog.w(TAG, "DisplayDeviceConfig file is null");
}
@@ -1415,6 +1537,7 @@
useFallbackProxSensor();
loadAutoBrightnessConfigsFromConfigXml();
loadAutoBrightnessAvailableFromConfigXml();
+ loadRefreshRateSetting(null);
mLoadedFrom = "<config.xml>";
}
@@ -1625,6 +1748,143 @@
}
}
+ private void loadRefreshRateSetting(DisplayConfiguration config) {
+ final RefreshRateConfigs refreshRateConfigs =
+ (config == null) ? null : config.getRefreshRate();
+ BlockingZoneConfig lowerBlockingZoneConfig =
+ (refreshRateConfigs == null) ? null
+ : refreshRateConfigs.getLowerBlockingZoneConfigs();
+ BlockingZoneConfig higherBlockingZoneConfig =
+ (refreshRateConfigs == null) ? null
+ : refreshRateConfigs.getHigherBlockingZoneConfigs();
+ loadLowerRefreshRateBlockingZones(lowerBlockingZoneConfig);
+ loadHigherRefreshRateBlockingZones(higherBlockingZoneConfig);
+ }
+
+
+ /**
+ * Loads the refresh rate configurations pertaining to the upper blocking zones.
+ */
+ private void loadLowerRefreshRateBlockingZones(BlockingZoneConfig lowerBlockingZoneConfig) {
+ loadLowerBlockingZoneDefaultRefreshRate(lowerBlockingZoneConfig);
+ loadLowerBrightnessThresholds(lowerBlockingZoneConfig);
+ }
+
+ /**
+ * Loads the refresh rate configurations pertaining to the upper blocking zones.
+ */
+ private void loadHigherRefreshRateBlockingZones(BlockingZoneConfig upperBlockingZoneConfig) {
+ loadHigherBlockingZoneDefaultRefreshRate(upperBlockingZoneConfig);
+ loadHigherBrightnessThresholds(upperBlockingZoneConfig);
+ }
+
+ /**
+ * Loads the default peak refresh rate. Internally, this takes care of loading
+ * the value from the display config, and if not present, falls back to config.xml.
+ */
+ private void loadHigherBlockingZoneDefaultRefreshRate(
+ BlockingZoneConfig upperBlockingZoneConfig) {
+ if (upperBlockingZoneConfig == null) {
+ mDefaultHighRefreshRate = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_defaultPeakRefreshRate);
+ } else {
+ mDefaultHighRefreshRate =
+ upperBlockingZoneConfig.getDefaultRefreshRate().intValue();
+ }
+ }
+
+ /**
+ * Loads the default refresh rate. Internally, this takes care of loading
+ * the value from the display config, and if not present, falls back to config.xml.
+ */
+ private void loadLowerBlockingZoneDefaultRefreshRate(
+ BlockingZoneConfig lowerBlockingZoneConfig) {
+ if (lowerBlockingZoneConfig == null) {
+ mDefaultLowRefreshRate = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_defaultRefreshRate);
+ } else {
+ mDefaultLowRefreshRate =
+ lowerBlockingZoneConfig.getDefaultRefreshRate().intValue();
+ }
+ }
+
+ /**
+ * Loads the lower brightness thresholds for refresh rate switching. Internally, this takes care
+ * of loading the value from the display config, and if not present, falls back to config.xml.
+ */
+ private void loadLowerBrightnessThresholds(BlockingZoneConfig lowerBlockingZoneConfig) {
+ if (lowerBlockingZoneConfig == null) {
+ mLowDisplayBrightnessThresholds = mContext.getResources().getIntArray(
+ R.array.config_brightnessThresholdsOfPeakRefreshRate);
+ mLowAmbientBrightnessThresholds = mContext.getResources().getIntArray(
+ R.array.config_ambientThresholdsOfPeakRefreshRate);
+ if (mLowDisplayBrightnessThresholds == null || mLowAmbientBrightnessThresholds == null
+ || mLowDisplayBrightnessThresholds.length
+ != mLowAmbientBrightnessThresholds.length) {
+ throw new RuntimeException("display low brightness threshold array and ambient "
+ + "brightness threshold array have different length: "
+ + "mLowDisplayBrightnessThresholds="
+ + Arrays.toString(mLowDisplayBrightnessThresholds)
+ + ", mLowAmbientBrightnessThresholds="
+ + Arrays.toString(mLowAmbientBrightnessThresholds));
+ }
+ } else {
+ List<DisplayBrightnessPoint> lowerThresholdDisplayBrightnessPoints =
+ lowerBlockingZoneConfig.getBlockingZoneThreshold().getDisplayBrightnessPoint();
+ int size = lowerThresholdDisplayBrightnessPoints.size();
+ mLowDisplayBrightnessThresholds = new int[size];
+ mLowAmbientBrightnessThresholds = new int[size];
+ for (int i = 0; i < size; i++) {
+ // We are explicitly casting this value to an integer to be able to reuse the
+ // existing DisplayBrightnessPoint type. It is fine to do this because the round off
+ // will have the negligible and unnoticeable impact on the loaded thresholds.
+ mLowDisplayBrightnessThresholds[i] = (int) lowerThresholdDisplayBrightnessPoints
+ .get(i).getNits().floatValue();
+ mLowAmbientBrightnessThresholds[i] = lowerThresholdDisplayBrightnessPoints
+ .get(i).getLux().intValue();
+ }
+ }
+ }
+
+ /**
+ * Loads the higher brightness thresholds for refresh rate switching. Internally, this takes
+ * care of loading the value from the display config, and if not present, falls back to
+ * config.xml.
+ */
+ private void loadHigherBrightnessThresholds(BlockingZoneConfig blockingZoneConfig) {
+ if (blockingZoneConfig == null) {
+ mHighDisplayBrightnessThresholds = mContext.getResources().getIntArray(
+ R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate);
+ mHighAmbientBrightnessThresholds = mContext.getResources().getIntArray(
+ R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate);
+ if (mHighAmbientBrightnessThresholds == null || mHighDisplayBrightnessThresholds == null
+ || mHighAmbientBrightnessThresholds.length
+ != mHighDisplayBrightnessThresholds.length) {
+ throw new RuntimeException("display high brightness threshold array and ambient "
+ + "brightness threshold array have different length: "
+ + "mHighDisplayBrightnessThresholds="
+ + Arrays.toString(mHighDisplayBrightnessThresholds)
+ + ", mHighAmbientBrightnessThresholds="
+ + Arrays.toString(mHighAmbientBrightnessThresholds));
+ }
+ } else {
+ List<DisplayBrightnessPoint> higherThresholdDisplayBrightnessPoints =
+ blockingZoneConfig.getBlockingZoneThreshold().getDisplayBrightnessPoint();
+ int size = higherThresholdDisplayBrightnessPoints.size();
+ mHighDisplayBrightnessThresholds = new int[size];
+ mHighAmbientBrightnessThresholds = new int[size];
+ for (int i = 0; i < size; i++) {
+ // We are explicitly casting this value to an integer to be able to reuse the
+ // existing DisplayBrightnessPoint type. It is fine to do this because the round off
+ // will have the negligible and unnoticeable impact on the loaded thresholds.
+ mHighDisplayBrightnessThresholds[i] = (int) higherThresholdDisplayBrightnessPoints
+ .get(i).getNits().floatValue();
+ mHighAmbientBrightnessThresholds[i] = higherThresholdDisplayBrightnessPoints
+ .get(i).getLux().intValue();
+ }
+ }
+ }
+
private void loadAutoBrightnessConfigValues(DisplayConfiguration config) {
final AutoBrightness autoBrightness = config.getAutoBrightness();
loadAutoBrightnessBrighteningLightDebounce(autoBrightness);
@@ -1951,6 +2211,14 @@
mProximitySensor.type = "";
}
+ private void loadScreenOffBrightnessSensorFromDdc(DisplayConfiguration config) {
+ final SensorDetails sensorDetails = config.getScreenOffBrightnessSensor();
+ if (sensorDetails != null) {
+ mScreenOffBrightnessSensor.type = sensorDetails.getType();
+ mScreenOffBrightnessSensor.name = sensorDetails.getName();
+ }
+ }
+
private void loadProxSensorFromDdc(DisplayConfiguration config) {
SensorDetails sensorDetails = config.getProxSensor();
if (sensorDetails != null) {
@@ -2363,6 +2631,19 @@
&& mDdcAutoBrightnessAvailable;
}
+ private void loadScreenOffBrightnessSensorValueToLuxFromDdc(DisplayConfiguration config) {
+ IntegerArray sensorValueToLux = config.getScreenOffBrightnessSensorValueToLux();
+ if (sensorValueToLux == null) {
+ return;
+ }
+
+ List<BigInteger> items = sensorValueToLux.getItem();
+ mScreenOffBrightnessSensorValueToLux = new int[items.size()];
+ for (int i = 0; i < items.size(); i++) {
+ mScreenOffBrightnessSensorValueToLux[i] = items.get(i).intValue();
+ }
+ }
+
static class SensorData {
public String type;
public String name;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index f9c8f06..8f35924 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -593,7 +593,7 @@
getBrightnessConfigForDisplayWithPdsFallbackLocked(
logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(),
userSerial);
- dpc.setBrightnessConfiguration(config);
+ dpc.setBrightnessConfiguration(config, /* shouldResetShortTermModel= */ true);
}
dpc.onSwitchUser(newUserId);
});
@@ -1890,7 +1890,7 @@
}
DisplayPowerController dpc = getDpcFromUniqueIdLocked(uniqueId);
if (dpc != null) {
- dpc.setBrightnessConfiguration(c);
+ dpc.setBrightnessConfiguration(c, /* shouldResetShortTermModel= */ true);
}
}
}
@@ -1939,7 +1939,8 @@
final DisplayPowerController dpc = mDisplayPowerControllers.get(
logicalDisplay.getDisplayIdLocked());
if (dpc != null) {
- dpc.setBrightnessConfiguration(config);
+ dpc.setBrightnessConfiguration(config,
+ /* shouldResetShortTermModel= */ false);
}
}
});
@@ -3652,44 +3653,21 @@
@Override
public Set<DisplayInfo> getPossibleDisplayInfo(int displayId) {
synchronized (mSyncRoot) {
- // Retrieve the group associated with this display id.
- final int displayGroupId =
- mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(displayId);
- if (displayGroupId == Display.INVALID_DISPLAY_GROUP) {
- Slog.w(TAG,
- "Can't get possible display info since display group for " + displayId
- + " does not exist");
- return new ArraySet<>();
- }
-
- // Assume any display in this group can be swapped out for the given display id.
Set<DisplayInfo> possibleInfo = new ArraySet<>();
- final DisplayGroup group = mLogicalDisplayMapper.getDisplayGroupLocked(
- displayGroupId);
- for (int i = 0; i < group.getSizeLocked(); i++) {
- final int id = group.getIdLocked(i);
- final LogicalDisplay logical = mLogicalDisplayMapper.getDisplayLocked(id);
- if (logical == null) {
- Slog.w(TAG,
- "Can't get possible display info since logical display for "
- + "display id " + id + " does not exist, as part of group "
- + displayGroupId);
- } else {
- possibleInfo.add(logical.getDisplayInfoLocked());
- }
- }
-
- // For the supported device states, retrieve the DisplayInfos for the logical
- // display layout.
+ // For each of supported device states, retrieve the display layout of that state,
+ // and return all of the DisplayInfos (one per state) for the given display id.
if (mDeviceStateManager == null) {
Slog.w(TAG, "Can't get supported states since DeviceStateManager not ready");
- } else {
- final int[] supportedStates =
- mDeviceStateManager.getSupportedStateIdentifiers();
- for (int state : supportedStates) {
- possibleInfo.addAll(
- mLogicalDisplayMapper.getDisplayInfoForStateLocked(state, displayId,
- displayGroupId));
+ return possibleInfo;
+ }
+ final int[] supportedStates =
+ mDeviceStateManager.getSupportedStateIdentifiers();
+ DisplayInfo displayInfo;
+ for (int state : supportedStates) {
+ displayInfo = mLogicalDisplayMapper.getDisplayInfoForStateLocked(state,
+ displayId);
+ if (displayInfo != null) {
+ possibleInfo.add(displayInfo);
}
}
return possibleInfo;
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index ecae833..6331a5d 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -1163,7 +1163,7 @@
mDefaultRefreshRate =
(displayDeviceConfig == null) ? (float) mContext.getResources().getInteger(
R.integer.config_defaultRefreshRate)
- : (float) displayDeviceConfig.getDefaultRefreshRate();
+ : (float) displayDeviceConfig.getDefaultLowRefreshRate();
}
public void observe() {
@@ -1250,7 +1250,7 @@
defaultPeakRefreshRate =
(displayDeviceConfig == null) ? (float) mContext.getResources().getInteger(
R.integer.config_defaultPeakRefreshRate)
- : (float) displayDeviceConfig.getDefaultPeakRefreshRate();
+ : (float) displayDeviceConfig.getDefaultHighRefreshRate();
}
mDefaultPeakRefreshRate = defaultPeakRefreshRate;
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index bb27651..d791c06 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -231,6 +231,9 @@
// True if should use light sensor to automatically determine doze screen brightness.
private final boolean mAllowAutoBrightnessWhileDozingConfig;
+ // True if the brightness config has changed and the short-term model needs to be reset
+ private boolean mShouldResetShortTermModel;
+
// Whether or not the color fade on screen on / off is enabled.
private final boolean mColorFadeEnabled;
@@ -411,7 +414,12 @@
@Nullable
private AutomaticBrightnessController mAutomaticBrightnessController;
+ // The controller for the sensor used to estimate ambient lux while the display is off.
+ @Nullable
+ private ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
+
private Sensor mLightSensor;
+ private Sensor mScreenOffBrightnessSensor;
// The mappers between ambient lux, display backlight values, and display brightness.
// We will switch between the idle mapper and active mapper in AutomaticBrightnessController.
@@ -459,6 +467,8 @@
// PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set.
private float mTemporaryAutoBrightnessAdjustment;
+ private boolean mUseAutoBrightness;
+
private boolean mIsRbcActive;
// Whether there's a callback to tell listeners the display has changed scheduled to run. When
@@ -692,6 +702,7 @@
public void onSwitchUser(@UserIdInt int newUserId) {
handleSettingsChange(true /* userSwitch */);
+ handleBrightnessModeChange();
if (mBrightnessTracker != null) {
mBrightnessTracker.onSwitchUser(newUserId);
}
@@ -941,6 +952,10 @@
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE),
+ false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
+ handleBrightnessModeChange();
}
private void setUpAutoBrightness(Resources resources, Handler handler) {
@@ -950,6 +965,13 @@
return;
}
+ float userLux = BrightnessMappingStrategy.NO_USER_LUX;
+ float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
+ if (mInteractiveModeBrightnessMapper != null) {
+ userLux = mInteractiveModeBrightnessMapper.getUserLux();
+ userBrightness = mInteractiveModeBrightnessMapper.getUserBrightness();
+ }
+
final boolean isIdleScreenBrightnessEnabled = resources.getBoolean(
R.bool.config_enableIdleScreenBrightnessMode);
mInteractiveModeBrightnessMapper = BrightnessMappingStrategy.create(resources,
@@ -1077,10 +1099,23 @@
ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext,
mHbmController, mBrightnessThrottler, mIdleModeBrightnessMapper,
mDisplayDeviceConfig.getAmbientHorizonShort(),
- mDisplayDeviceConfig.getAmbientHorizonLong());
+ mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness);
mBrightnessEventRingBuffer =
new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
+
+ loadScreenOffBrightnessSensor();
+ int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
+ if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
+ mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController(
+ mSensorManager,
+ mScreenOffBrightnessSensor,
+ mHandler,
+ SystemClock::uptimeMillis,
+ sensorValueToLux,
+ mInteractiveModeBrightnessMapper
+ );
+ }
} else {
mUseSoftwareAutoBrightnessConfig = false;
}
@@ -1258,6 +1293,12 @@
}
assert(state != Display.STATE_UNKNOWN);
+ if (mScreenOffBrightnessSensorController != null) {
+ mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
+ && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
+ && !mAllowAutoBrightnessWhileDozingConfig)));
+ }
+
boolean skipRampBecauseOfProximityChangeToNegative = false;
// Apply the proximity sensor.
if (mProximitySensor != null) {
@@ -1344,11 +1385,11 @@
final boolean autoBrightnessEnabledInDoze =
mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
- final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
+ final boolean autoBrightnessEnabled = mUseAutoBrightness
&& (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
&& Float.isNaN(brightnessState)
&& mAutomaticBrightnessController != null;
- final boolean autoBrightnessDisabledDueToDisplayOff = mPowerRequest.useAutoBrightness
+ final boolean autoBrightnessDisabledDueToDisplayOff = mUseAutoBrightness
&& !(state == Display.STATE_ON || autoBrightnessEnabledInDoze);
final int autoBrightnessState = autoBrightnessEnabled
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
@@ -1406,7 +1447,9 @@
mBrightnessConfiguration,
mLastUserSetScreenBrightness,
userSetBrightnessChanged, autoBrightnessAdjustment,
- autoBrightnessAdjustmentChanged, mPowerRequest.policy);
+ autoBrightnessAdjustmentChanged, mPowerRequest.policy,
+ mShouldResetShortTermModel);
+ mShouldResetShortTermModel = false;
}
if (mBrightnessTracker != null) {
@@ -1435,6 +1478,9 @@
updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
mAppliedAutoBrightness = true;
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
+ if (mScreenOffBrightnessSensorController != null) {
+ mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
+ }
} else {
mAppliedAutoBrightness = false;
}
@@ -1462,6 +1508,19 @@
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
}
+ // The ALS is not available yet - use the screen off sensor to determine the initial
+ // brightness
+ if (Float.isNaN(brightnessState) && autoBrightnessEnabled
+ && mScreenOffBrightnessSensorController != null) {
+ brightnessState = mScreenOffBrightnessSensorController.getAutomaticScreenBrightness();
+ if (isValidBrightnessValue(brightnessState)) {
+ brightnessState = clampScreenBrightness(brightnessState);
+ updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
+ mBrightnessReasonTemp.setReason(
+ BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR);
+ }
+ }
+
// Apply manual brightness.
if (Float.isNaN(brightnessState)) {
brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
@@ -1700,7 +1759,7 @@
|| brightnessAdjustmentFlags != 0) {
float lastBrightness = mLastBrightnessEvent.brightness;
mTempBrightnessEvent.initialBrightness = lastBrightness;
- mTempBrightnessEvent.automaticBrightnessEnabled = mPowerRequest.useAutoBrightness;
+ mTempBrightnessEvent.automaticBrightnessEnabled = mUseAutoBrightness;
mLastBrightnessEvent.copyFrom(mTempBrightnessEvent);
BrightnessEvent newEvent = new BrightnessEvent(mTempBrightnessEvent);
@@ -1800,8 +1859,10 @@
mHandler.sendEmptyMessage(MSG_IGNORE_PROXIMITY);
}
- public void setBrightnessConfiguration(BrightnessConfiguration c) {
- Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS, c);
+ public void setBrightnessConfiguration(BrightnessConfiguration c,
+ boolean shouldResetShortTermModel) {
+ Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS,
+ shouldResetShortTermModel ? 1 : 0, /* unused */ 0, c);
msg.sendToTarget();
}
@@ -2031,6 +2092,14 @@
fallbackType);
}
+ private void loadScreenOffBrightnessSensor() {
+ DisplayDeviceConfig.SensorData screenOffBrightnessSensor =
+ mDisplayDeviceConfig.getScreenOffBrightnessSensor();
+ mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager,
+ screenOffBrightnessSensor.type, screenOffBrightnessSensor.name,
+ SensorUtils.NO_FALLBACK);
+ }
+
private void loadProximitySensor() {
if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
return;
@@ -2372,6 +2441,18 @@
sendUpdatePowerState();
}
+ private void handleBrightnessModeChange() {
+ final int screenBrightnessModeSetting = Settings.System.getIntForUser(
+ mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
+ mHandler.post(() -> {
+ mUseAutoBrightness = screenBrightnessModeSetting
+ == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
+ updatePowerState();
+ });
+ }
+
private float getAutoBrightnessAdjustmentSetting() {
final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
@@ -2461,7 +2542,7 @@
private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated,
boolean hadUserDataPoint) {
final float brightnessInNits = convertToNits(brightness);
- if (mPowerRequest.useAutoBrightness && brightnessInNits >= 0.0f
+ if (mUseAutoBrightness && brightnessInNits >= 0.0f
&& mAutomaticBrightnessController != null && mBrightnessTracker != null) {
// We only want to track changes on devices that can actually map the display backlight
// values into a physical brightness unit since the value provided by the API is in
@@ -3027,6 +3108,7 @@
break;
case MSG_CONFIGURE_BRIGHTNESS:
mBrightnessConfiguration = (BrightnessConfiguration) msg.obj;
+ mShouldResetShortTermModel = msg.arg1 == 1;
updatePowerState();
break;
@@ -3099,7 +3181,11 @@
@Override
public void onChange(boolean selfChange, Uri uri) {
- handleSettingsChange(false /* userSwitch */);
+ if (uri.equals(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE))) {
+ handleBrightnessModeChange();
+ } else {
+ handleSettingsChange(false /* userSwitch */);
+ }
}
}
@@ -3163,7 +3249,8 @@
static final int REASON_OVERRIDE = 7;
static final int REASON_TEMPORARY = 8;
static final int REASON_BOOST = 9;
- static final int REASON_MAX = REASON_BOOST;
+ static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 10;
+ static final int REASON_MAX = REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
static final int MODIFIER_DIMMED = 0x1;
static final int MODIFIER_LOW_POWER = 0x2;
@@ -3273,6 +3360,7 @@
case REASON_OVERRIDE: return "override";
case REASON_TEMPORARY: return "temporary";
case REASON_BOOST: return "boost";
+ case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR: return "screen_off_brightness_sensor";
default: return Integer.toString(reason);
}
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 778e418..bf576b8 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -19,6 +19,7 @@
import static android.view.Display.DEFAULT_DISPLAY;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.hardware.devicestate.DeviceStateManager;
import android.os.Handler;
@@ -28,7 +29,6 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.text.TextUtils;
-import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.SparseArray;
@@ -43,7 +43,6 @@
import java.io.PrintWriter;
import java.util.Arrays;
-import java.util.Set;
import java.util.function.Consumer;
/**
@@ -304,58 +303,44 @@
}
/**
- * Returns the set of {@link DisplayInfo} for this device state, only fetching the info that is
- * part of the same display group as the provided display id. The DisplayInfo represent the
- * logical display layouts possible for the given device state.
+ * Returns the {@link DisplayInfo} for this device state, indicated by the given display id. The
+ * DisplayInfo represents the attributes of the indicated display in the layout associated with
+ * this state. This is used to get display information for various displays in various states;
+ * e.g. to help apps preload resources for the possible display states.
*
* @param deviceState the state to query possible layouts for
- * @param displayId the display id to apply to all displays within the group
- * @param groupId the display group to filter display info for. Must be the same group as
- * the display with the provided display id.
+ * @param displayId the display id to retrieve
+ * @return {@code null} if no corresponding {@link DisplayInfo} could be found, or the
+ * {@link DisplayInfo} with a matching display id.
*/
- public Set<DisplayInfo> getDisplayInfoForStateLocked(int deviceState, int displayId,
- int groupId) {
- Set<DisplayInfo> displayInfos = new ArraySet<>();
+ @Nullable
+ public DisplayInfo getDisplayInfoForStateLocked(int deviceState, int displayId) {
+ // Retrieve the layout for this particular state.
final Layout layout = mDeviceStateToLayoutMap.get(deviceState);
- final int layoutSize = layout.size();
- for (int i = 0; i < layoutSize; i++) {
- Layout.Display displayLayout = layout.getAt(i);
- if (displayLayout == null) {
- continue;
- }
-
- // If the underlying display-device we want to use for this display
- // doesn't exist, then skip it. This can happen at startup as display-devices
- // trickle in one at a time. When the new display finally shows up, the layout is
- // recalculated so that the display is properly added to the current layout.
- final DisplayAddress address = displayLayout.getAddress();
- final DisplayDevice device = mDisplayDeviceRepo.getByAddressLocked(address);
- if (device == null) {
- Slog.w(TAG, "The display device (" + address + "), is not available"
- + " for the display state " + deviceState);
- continue;
- }
-
- // Find or create the LogicalDisplay to map the DisplayDevice to.
- final int logicalDisplayId = displayLayout.getLogicalDisplayId();
- final LogicalDisplay logicalDisplay = getDisplayLocked(logicalDisplayId);
- if (logicalDisplay == null) {
- Slog.w(TAG, "The logical display (" + address + "), is not available"
- + " for the display state " + deviceState);
- continue;
- }
- final DisplayInfo temp = logicalDisplay.getDisplayInfoLocked();
- DisplayInfo displayInfo = new DisplayInfo(temp);
- if (displayInfo.displayGroupId != groupId) {
- // Ignore any displays not in the provided group.
- continue;
- }
- // A display in the same group can be swapped out at any point, so set the display id
- // for all results to the provided display id.
- displayInfo.displayId = displayId;
- displayInfos.add(displayInfo);
+ if (layout == null) {
+ return null;
}
- return displayInfos;
+ // Retrieve the details of the given display within this layout.
+ Layout.Display display = layout.getById(displayId);
+ if (display == null) {
+ return null;
+ }
+ // Retrieve the display info for the display that matches the display id.
+ final DisplayDevice device = mDisplayDeviceRepo.getByAddressLocked(display.getAddress());
+ if (device == null) {
+ Slog.w(TAG, "The display device (" + display.getAddress() + "), is not available"
+ + " for the display state " + mDeviceState);
+ return null;
+ }
+ LogicalDisplay logicalDisplay = getDisplayLocked(device, /* includeDisabled= */ true);
+ if (logicalDisplay == null) {
+ Slog.w(TAG, "The logical display associated with address (" + display.getAddress()
+ + "), is not available for the display state " + mDeviceState);
+ return null;
+ }
+ DisplayInfo displayInfo = new DisplayInfo(logicalDisplay.getDisplayInfoLocked());
+ displayInfo.displayId = displayId;
+ return displayInfo;
}
public void dumpLocked(PrintWriter pw) {
@@ -426,7 +411,8 @@
// Send the device to sleep when required.
mHandler.post(() -> {
mPowerManager.goToSleep(SystemClock.uptimeMillis(),
- PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD, 0);
+ PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD,
+ PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
});
}
}
diff --git a/services/core/java/com/android/server/display/ScreenOffBrightnessSensorController.java b/services/core/java/com/android/server/display/ScreenOffBrightnessSensorController.java
new file mode 100644
index 0000000..6f50dac
--- /dev/null
+++ b/services/core/java/com/android/server/display/ScreenOffBrightnessSensorController.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import android.annotation.Nullable;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.util.IndentingPrintWriter;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+
+/**
+ * Controls the light sensor when the screen is off. The sensor used here does not report lux values
+ * but an index that needs to be mapped to a lux value.
+ */
+public class ScreenOffBrightnessSensorController implements SensorEventListener {
+ private static final String TAG = "ScreenOffBrightnessSensorController";
+
+ private static final int SENSOR_INVALID_VALUE = -1;
+ private static final long SENSOR_VALUE_VALID_TIME_MILLIS = 1500;
+
+ private final Handler mHandler;
+ private final Clock mClock;
+ private final SensorManager mSensorManager;
+ private final Sensor mLightSensor;
+ private final int[] mSensorValueToLux;
+
+ private boolean mRegistered;
+ private int mLastSensorValue = SENSOR_INVALID_VALUE;
+ private long mSensorDisableTime = -1;
+
+ // The mapper to translate ambient lux to screen brightness in the range [0, 1.0].
+ @Nullable
+ private final BrightnessMappingStrategy mBrightnessMapper;
+
+ public ScreenOffBrightnessSensorController(
+ SensorManager sensorManager,
+ Sensor lightSensor,
+ Handler handler,
+ Clock clock,
+ int[] sensorValueToLux,
+ BrightnessMappingStrategy brightnessMapper) {
+ mSensorManager = sensorManager;
+ mLightSensor = lightSensor;
+ mHandler = handler;
+ mClock = clock;
+ mSensorValueToLux = sensorValueToLux;
+ mBrightnessMapper = brightnessMapper;
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (mRegistered) {
+ mLastSensorValue = (int) event.values[0];
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+
+ void setLightSensorEnabled(boolean enabled) {
+ if (enabled && !mRegistered) {
+ // Wait until we get an event from the sensor indicating ready.
+ mRegistered = mSensorManager.registerListener(this, mLightSensor,
+ SensorManager.SENSOR_DELAY_NORMAL, mHandler);
+ mLastSensorValue = SENSOR_INVALID_VALUE;
+ } else if (!enabled && mRegistered) {
+ mSensorManager.unregisterListener(this);
+ mRegistered = false;
+ mSensorDisableTime = mClock.uptimeMillis();
+ }
+ }
+
+ float getAutomaticScreenBrightness() {
+ if (mLastSensorValue < 0 || mLastSensorValue >= mSensorValueToLux.length
+ || (!mRegistered
+ && mClock.uptimeMillis() - mSensorDisableTime > SENSOR_VALUE_VALID_TIME_MILLIS)) {
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ }
+
+ int lux = mSensorValueToLux[mLastSensorValue];
+ if (lux < 0) {
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ }
+
+ return mBrightnessMapper.getBrightness(lux);
+ }
+
+ /** Dump current state */
+ public void dump(PrintWriter pw) {
+ pw.println("ScreenOffBrightnessSensorController:");
+ IndentingPrintWriter idpw = new IndentingPrintWriter(pw);
+ idpw.increaseIndent();
+ idpw.println("registered=" + mRegistered);
+ idpw.println("lastSensorValue=" + mLastSensorValue);
+ }
+
+ /** Functional interface for providing time. */
+ @VisibleForTesting
+ interface Clock {
+ /**
+ * Returns current time in milliseconds since boot, not counting time spent in deep sleep.
+ */
+ long uptimeMillis();
+ }
+}
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index d328fd7..bb1e393 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -56,6 +56,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.service.dreams.DreamManagerInternal;
import android.service.dreams.DreamService;
@@ -113,6 +114,7 @@
private final PowerManagerInternal mPowerManagerInternal;
private final PowerManager.WakeLock mDozeWakeLock;
private final ActivityTaskManagerInternal mAtmInternal;
+ private final UserManager mUserManager;
private final UiEventLogger mUiEventLogger;
private final DreamUiEventLogger mDreamUiEventLogger;
private final ComponentName mAmbientDisplayComponent;
@@ -212,6 +214,7 @@
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mPowerManagerInternal = getLocalService(PowerManagerInternal.class);
mAtmInternal = getLocalService(ActivityTaskManagerInternal.class);
+ mUserManager = context.getSystemService(UserManager.class);
mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, DOZE_WAKE_LOCK_TAG);
mDozeConfig = new AmbientDisplayConfiguration(mContext);
mUiEventLogger = new UiEventLoggerImpl();
@@ -383,6 +386,10 @@
return false;
}
+ if (!mUserManager.isUserUnlocked()) {
+ return false;
+ }
+
if ((mWhenToDream & DREAM_ON_CHARGE) == DREAM_ON_CHARGE) {
return mIsCharging;
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 1ea949e..2f818fa 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -123,6 +123,7 @@
import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_NOTIFICATION_BOOL;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
import static com.android.internal.util.ArrayUtils.appendInt;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -3148,7 +3149,8 @@
* active merge set [A,B], we'd return a new template that primarily matches
* A, but also matches B.
*/
- private static NetworkTemplate normalizeTemplate(@NonNull NetworkTemplate template,
+ @VisibleForTesting(visibility = PRIVATE)
+ static NetworkTemplate normalizeTemplate(@NonNull NetworkTemplate template,
@NonNull List<String[]> mergedList) {
// Now there are several types of network which uses Subscriber Id to store network
// information. For instance:
@@ -3158,6 +3160,12 @@
if (template.getSubscriberIds().isEmpty()) return template;
for (final String[] merged : mergedList) {
+ // In some rare cases (e.g. b/243015487), merged subscriberId list might contain
+ // duplicated items. Deduplication for better error handling.
+ final ArraySet mergedSet = new ArraySet(merged);
+ if (mergedSet.size() != merged.length) {
+ Log.wtf(TAG, "Duplicated merged list detected: " + Arrays.toString(merged));
+ }
// TODO: Handle incompatible subscriberIds if that happens in practice.
for (final String subscriberId : template.getSubscriberIds()) {
if (com.android.net.module.util.CollectionUtils.contains(merged, subscriberId)) {
@@ -3165,7 +3173,7 @@
// a template that matches all merged subscribers.
return new NetworkTemplate.Builder(template.getMatchRule())
.setWifiNetworkKeys(template.getWifiNetworkKeys())
- .setSubscriberIds(Set.of(merged))
+ .setSubscriberIds(mergedSet)
.setMeteredness(template.getMeteredness())
.build();
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 1ea0984..8d2714c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3395,6 +3395,11 @@
enforceOwnerRights(snapshot, ownerPackage, callingUid);
PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
+ if (!intentFilter.checkDataPathAndSchemeSpecificParts()) {
+ EventLog.writeEvent(0x534e4554, "246749936", callingUid);
+ throw new IllegalArgumentException("Invalid intent data paths or scheme specific parts"
+ + " in the filter.");
+ }
if (intentFilter.countActions() == 0) {
Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
return;
diff --git a/services/core/java/com/android/server/pm/PreferredActivityHelper.java b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
index 9befd6e..2b092b9 100644
--- a/services/core/java/com/android/server/pm/PreferredActivityHelper.java
+++ b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
@@ -37,6 +37,7 @@
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.EventLog;
import android.util.Log;
import android.util.LogPrinter;
import android.util.PrintStreamPrinter;
@@ -388,6 +389,11 @@
throw new SecurityException(
"addPersistentPreferredActivity can only be run by the system");
}
+ if (!filter.checkDataPathAndSchemeSpecificParts()) {
+ EventLog.writeEvent(0x534e4554, "246749702", callingUid);
+ throw new IllegalArgumentException("Invalid intent data paths or scheme specific parts"
+ + " in the filter.");
+ }
if (filter.countActions() == 0) {
Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
return;
diff --git a/services/core/java/com/android/server/pm/WatchedIntentFilter.java b/services/core/java/com/android/server/pm/WatchedIntentFilter.java
index 5d7a2a3..09cf094 100644
--- a/services/core/java/com/android/server/pm/WatchedIntentFilter.java
+++ b/services/core/java/com/android/server/pm/WatchedIntentFilter.java
@@ -671,6 +671,13 @@
}
/**
+ * @see IntentFilter#checkDataPathAndSchemeSpecificParts()
+ */
+ public boolean checkDataPathAndSchemeSpecificParts() {
+ return mFilter.checkDataPathAndSchemeSpecificParts();
+ }
+
+ /**
* @see IntentFilter#getHostsList()
*/
public ArrayList<String> getHostsList() {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 85a2a5d..de0d1f8 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1049,25 +1049,18 @@
return;
}
- // Make sure the device locks. Unfortunately, this has the side-effect of briefly revealing
- // the lock screen before the dream appears. Note that this locking behavior needs to
- // happen regardless of whether we end up dreaming (below) or not.
- // TODO(b/261662912): Find a better way to lock the device that doesn't result in jank.
- lockNow(null);
-
- // Don't dream if the user isn't user zero.
- // TODO(b/261907079): Move this check to DreamManagerService#canStartDreamingInternal().
- if (ActivityManager.getCurrentUser() != UserHandle.USER_SYSTEM) {
- noDreamAction.run();
- return;
- }
-
final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
if (dreamManagerInternal == null || !dreamManagerInternal.canStartDreaming(isScreenOn)) {
noDreamAction.run();
return;
}
+ // Make sure the device locks. Unfortunately, this has the side-effect of briefly revealing
+ // the lock screen before the dream appears. Note that locking is a side-effect of the no
+ // dream action that is executed if we early return above.
+ // TODO(b/261662912): Find a better way to lock the device that doesn't result in jank.
+ lockNow(null);
+
dreamManagerInternal.requestDream();
}
diff --git a/services/core/java/com/android/server/power/PowerGroup.java b/services/core/java/com/android/server/power/PowerGroup.java
index 431cf38..3a3f6b2 100644
--- a/services/core/java/com/android/server/power/PowerGroup.java
+++ b/services/core/java/com/android/server/power/PowerGroup.java
@@ -28,6 +28,8 @@
import static com.android.server.power.PowerManagerService.WAKE_LOCK_DOZE;
import static com.android.server.power.PowerManagerService.WAKE_LOCK_DRAW;
import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIGHT;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_DIM;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_STAY_AWAKE;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
@@ -341,6 +343,22 @@
return mWakeLockSummary;
}
+ /**
+ * Query whether a wake lock is at least partially responsible for keeping the device awake.
+ *
+ * This does not necessarily mean the wake lock is the sole reason the device is awake; there
+ * could also be user activity keeping the device awake, for example. It just means a wake lock
+ * is being held that would keep the device awake even if nothing else was.
+ *
+ * @return whether the PowerGroup is being kept awake at least in part because a wake lock is
+ * being held.
+ */
+ public boolean hasWakeLockKeepingScreenOnLocked() {
+ final int screenOnWakeLockMask =
+ WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM | WAKE_LOCK_STAY_AWAKE;
+ return (mWakeLockSummary & (screenOnWakeLockMask)) != 0;
+ }
+
public void setWakeLockSummaryLocked(int summary) {
mWakeLockSummary = summary;
}
@@ -419,16 +437,14 @@
return mDisplayPowerRequest.policy;
}
- boolean updateLocked(float screenBrightnessOverride, boolean autoBrightness,
- boolean useProximitySensor, boolean boostScreenBrightness, int dozeScreenState,
- float dozeScreenBrightness, boolean overrideDrawWakeLock,
- PowerSaveState powerSaverState, boolean quiescent, boolean dozeAfterScreenOff,
- boolean vrModeEnabled, boolean bootCompleted, boolean screenBrightnessBoostInProgress,
- boolean waitForNegativeProximity) {
+ boolean updateLocked(float screenBrightnessOverride, boolean useProximitySensor,
+ boolean boostScreenBrightness, int dozeScreenState, float dozeScreenBrightness,
+ boolean overrideDrawWakeLock, PowerSaveState powerSaverState, boolean quiescent,
+ boolean dozeAfterScreenOff, boolean vrModeEnabled, boolean bootCompleted,
+ boolean screenBrightnessBoostInProgress, boolean waitForNegativeProximity) {
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(quiescent, dozeAfterScreenOff,
vrModeEnabled, bootCompleted, screenBrightnessBoostInProgress);
mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
- mDisplayPowerRequest.useAutoBrightness = autoBrightness;
mDisplayPowerRequest.useProximitySensor = useProximitySensor;
mDisplayPowerRequest.boostScreenBrightness = boostScreenBrightness;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index b1c986e..651bb93 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -584,10 +584,6 @@
private boolean mIsFaceDown = false;
private long mLastFlipTime = 0L;
- // The screen brightness mode.
- // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
- private int mScreenBrightnessModeSetting;
-
// The screen brightness setting override from the window manager
// to allow the current foreground activity to override the brightness.
private float mScreenBrightnessOverrideFromWindowManager =
@@ -1481,10 +1477,6 @@
mSystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, retailDemoValue);
}
- mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
-
mDirty |= DIRTY_SETTINGS;
}
@@ -3466,23 +3458,18 @@
final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
final int groupId = powerGroup.getGroupId();
- // Determine appropriate screen brightness and auto-brightness adjustments.
- final boolean autoBrightness;
+ // Determine appropriate screen brightness.
final float screenBrightnessOverride;
if (!mBootCompleted) {
// Keep the brightness steady during boot. This requires the
// bootloader brightness and the default brightness to be identical.
- autoBrightness = false;
screenBrightnessOverride = mScreenBrightnessDefault;
} else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
- autoBrightness = false;
screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;
} else {
- autoBrightness = (mScreenBrightnessModeSetting
- == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
- boolean ready = powerGroup.updateLocked(screenBrightnessOverride, autoBrightness,
+ boolean ready = powerGroup.updateLocked(screenBrightnessOverride,
shouldUseProximitySensorLocked(), shouldBoostScreenBrightness(),
mDozeScreenStateOverrideFromDreamManager,
mDozeScreenBrightnessOverrideFromDreamManagerFloat,
@@ -3503,7 +3490,6 @@
powerGroup.getUserActivitySummaryLocked())
+ ", mBootCompleted=" + mBootCompleted
+ ", screenBrightnessOverride=" + screenBrightnessOverride
- + ", useAutoBrightness=" + autoBrightness
+ ", mScreenBrightnessBoostInProgress="
+ mScreenBrightnessBoostInProgress
+ ", mIsVrModeEnabled= " + mIsVrModeEnabled
@@ -4525,7 +4511,6 @@
+ mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
+ isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
pw.println(" mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting);
- pw.println(" mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
pw.println(" mScreenBrightnessOverrideFromWindowManager="
+ mScreenBrightnessOverrideFromWindowManager);
pw.println(" mUserActivityTimeoutOverrideFromWindowManager="
@@ -4904,9 +4889,6 @@
proto.end(stayOnWhilePluggedInToken);
proto.write(
- PowerServiceSettingsAndConfigurationDumpProto.SCREEN_BRIGHTNESS_MODE_SETTING,
- mScreenBrightnessModeSetting);
- proto.write(
PowerServiceSettingsAndConfigurationDumpProto
.SCREEN_BRIGHTNESS_OVERRIDE_FROM_WINDOW_MANAGER,
mScreenBrightnessOverrideFromWindowManager);
@@ -5778,6 +5760,11 @@
try {
synchronized (mLock) {
PowerGroup defaultPowerGroup = mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP);
+ if ((flags & PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP) != 0) {
+ if (defaultPowerGroup.hasWakeLockKeepingScreenOnLocked()) {
+ return;
+ }
+ }
if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
sleepPowerGroupLocked(defaultPowerGroup, eventTime, reason, uid);
} else {
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index dfa1281..8cc1f12 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -16,9 +16,11 @@
package com.android.server.power.hint;
+import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.IUidObserver;
+import android.app.StatsManager;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
@@ -26,13 +28,17 @@
import android.os.IHintSession;
import android.os.Process;
import android.os.RemoteException;
+import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseArray;
+import android.util.StatsEvent;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
import com.android.server.LocalServices;
@@ -52,7 +58,7 @@
private static final boolean DEBUG = false;
@VisibleForTesting final long mHintSessionPreferredRate;
- // Multi-levle map storing all active AppHintSessions.
+ // Multi-level map storing all active AppHintSessions.
// First level is keyed by the UID of the client process creating the session.
// Second level is keyed by an IBinder passed from client process. This is used to observe
// when the process exits. The client generally uses the same IBinder object across multiple
@@ -69,6 +75,11 @@
private final ActivityManagerInternal mAmInternal;
+ private final Context mContext;
+
+ private static final String PROPERTY_SF_ENABLE_CPU_HINT = "debug.sf.enable_adpf_cpu_hint";
+ private static final String PROPERTY_HWUI_ENABLE_HINT_MANAGER = "debug.hwui.use_hint_manager";
+
@VisibleForTesting final IHintManager.Stub mService = new BinderService();
public HintManagerService(Context context) {
@@ -78,6 +89,7 @@
@VisibleForTesting
HintManagerService(Context context, Injector injector) {
super(context);
+ mContext = context;
mActiveSessions = new ArrayMap<>();
mNativeWrapper = injector.createNativeWrapper();
mNativeWrapper.halInit();
@@ -108,6 +120,9 @@
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
systemReady();
}
+ if (phase == SystemService.PHASE_BOOT_COMPLETED) {
+ registerStatsCallbacks();
+ }
}
private void systemReady() {
@@ -122,6 +137,30 @@
}
+ private void registerStatsCallbacks() {
+ final StatsManager statsManager = mContext.getSystemService(StatsManager.class);
+ statsManager.setPullAtomCallback(
+ FrameworkStatsLog.ADPF_SYSTEM_COMPONENT_INFO,
+ null, // use default PullAtomMetadata values
+ BackgroundThread.getExecutor(),
+ this::onPullAtom);
+ }
+
+ private int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) {
+ if (atomTag == FrameworkStatsLog.ADPF_SYSTEM_COMPONENT_INFO) {
+ final boolean isSurfaceFlingerUsingCpuHint =
+ SystemProperties.getBoolean(PROPERTY_SF_ENABLE_CPU_HINT, false);
+ final boolean isHwuiHintManagerEnabled =
+ SystemProperties.getBoolean(PROPERTY_HWUI_ENABLE_HINT_MANAGER, false);
+
+ data.add(FrameworkStatsLog.buildStatsEvent(
+ FrameworkStatsLog.ADPF_SYSTEM_COMPONENT_INFO,
+ isSurfaceFlingerUsingCpuHint,
+ isHwuiHintManagerEnabled));
+ }
+ return android.app.StatsManager.PULL_SUCCESS;
+ }
+
/**
* Wrapper around the static-native methods from native.
*
@@ -326,6 +365,7 @@
AppHintSession hs = new AppHintSession(callingUid, callingTgid, tids, token,
halSessionPtr, durationNanos);
+ logPerformanceHintSessionAtom(callingUid, halSessionPtr, durationNanos, tids);
synchronized (mLock) {
ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap =
mActiveSessions.get(callingUid);
@@ -374,6 +414,12 @@
}
}
}
+
+ private void logPerformanceHintSessionAtom(int uid, long sessionId,
+ long targetDuration, int[] tids) {
+ FrameworkStatsLog.write(FrameworkStatsLog.PERFORMANCE_HINT_SESSION_REPORTED, uid,
+ sessionId, targetDuration, tids.length);
+ }
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 2888b9a..afe8d3e 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -563,7 +563,12 @@
changed = mUserIsTrusted.get(userId) != trusted;
mUserIsTrusted.put(userId, trusted);
}
- dispatchOnTrustChanged(trusted, userId, flags, getTrustGrantedMessages(userId));
+ dispatchOnTrustChanged(
+ trusted,
+ false /* newlyUnlocked */,
+ userId,
+ flags,
+ getTrustGrantedMessages(userId));
if (changed) {
refreshDeviceLockedForUser(userId);
if (!trusted) {
@@ -628,7 +633,9 @@
if (DEBUG) Slog.d(TAG, "pendingTrustState: " + pendingTrustState);
boolean isNowTrusted = pendingTrustState == TrustState.TRUSTED;
- dispatchOnTrustChanged(isNowTrusted, userId, flags, getTrustGrantedMessages(userId));
+ boolean newlyUnlocked = !alreadyUnlocked && isNowTrusted;
+ dispatchOnTrustChanged(
+ isNowTrusted, newlyUnlocked, userId, flags, getTrustGrantedMessages(userId));
if (isNowTrusted != wasTrusted) {
refreshDeviceLockedForUser(userId);
if (!isNowTrusted) {
@@ -643,8 +650,7 @@
}
}
- boolean wasLocked = !alreadyUnlocked;
- boolean shouldSendCallback = wasLocked && pendingTrustState == TrustState.TRUSTED;
+ boolean shouldSendCallback = newlyUnlocked;
if (shouldSendCallback) {
if (resultCallback != null) {
if (DEBUG) Slog.d(TAG, "calling back with UNLOCKED_BY_GRANT");
@@ -690,7 +696,7 @@
*/
public void lockUser(int userId) {
mLockPatternUtils.requireStrongAuth(
- StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, userId);
+ StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED, userId);
try {
WindowManagerGlobal.getWindowManagerService().lockNow(null);
} catch (RemoteException e) {
@@ -1387,16 +1393,17 @@
}
}
- private void dispatchOnTrustChanged(boolean enabled, int userId, int flags,
- @NonNull List<String> trustGrantedMessages) {
+ private void dispatchOnTrustChanged(boolean enabled, boolean newlyUnlocked, int userId,
+ int flags, @NonNull List<String> trustGrantedMessages) {
if (DEBUG) {
- Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
+ Log.i(TAG, "onTrustChanged(" + enabled + ", " + newlyUnlocked + ", " + userId + ", 0x"
+ Integer.toHexString(flags) + ")");
}
if (!enabled) flags = 0;
for (int i = 0; i < mTrustListeners.size(); i++) {
try {
- mTrustListeners.get(i).onTrustChanged(enabled, userId, flags, trustGrantedMessages);
+ mTrustListeners.get(i).onTrustChanged(
+ enabled, newlyUnlocked, userId, flags, trustGrantedMessages);
} catch (DeadObjectException e) {
Slog.d(TAG, "Removing dead TrustListener.");
mTrustListeners.remove(i);
@@ -2087,7 +2094,7 @@
if (mStrongAuthTracker.isTrustAllowedForUser(mUserId)) {
if (DEBUG) Slog.d(TAG, "Revoking all trust because of trust timeout");
mLockPatternUtils.requireStrongAuth(
- mStrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, mUserId);
+ mStrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED, mUserId);
}
maybeLockScreen(mUserId);
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e639866..418e1ed 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -7756,10 +7756,6 @@
// configuration. This is important to cases where activities with incompatible
// orientations launch, or user goes back from an activity of bi-orientation to an
// activity with specified orientation.
- if (getRequestedOrientation() == SCREEN_ORIENTATION_UNSET) {
- return;
- }
-
if (onDescendantOrientationChanged(this)) {
// WM Shell can show additional UI elements, e.g. a restart button for size compat mode
// so ensure that WM Shell is called when an activity becomes visible.
@@ -8329,7 +8325,8 @@
// If orientation is respected when insets are applied, then stableBounds will be empty.
boolean orientationRespectedWithInsets =
orientationRespectedWithInsets(parentBounds, stableBounds);
- if (handlesOrientationChangeFromDescendant() && orientationRespectedWithInsets) {
+ if (orientationRespectedWithInsets
+ && handlesOrientationChangeFromDescendant(mOrientation)) {
// No need to letterbox because of fixed orientation. Display will handle
// fixed-orientation requests and a display rotation is enough to respect requested
// orientation with insets applied.
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index a32e460..af5bd14 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -34,6 +34,8 @@
import static com.android.server.wm.WindowContainerChildProto.DISPLAY_AREA;
import android.annotation.Nullable;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
@@ -141,26 +143,30 @@
}
@Override
+ @ScreenOrientation
int getOrientation(int candidate) {
- mLastOrientationSource = null;
- if (getIgnoreOrientationRequest()) {
+ final int orientation = super.getOrientation(candidate);
+ if (getIgnoreOrientationRequest(orientation)) {
+ // In all the other case, mLastOrientationSource will be reassigned to a new value
+ mLastOrientationSource = null;
return SCREEN_ORIENTATION_UNSET;
}
-
- return super.getOrientation(candidate);
+ return orientation;
}
@Override
- boolean handlesOrientationChangeFromDescendant() {
- return !getIgnoreOrientationRequest()
- && super.handlesOrientationChangeFromDescendant();
+ boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
+ return !getIgnoreOrientationRequest(orientation)
+ && super.handlesOrientationChangeFromDescendant(orientation);
}
@Override
- boolean onDescendantOrientationChanged(WindowContainer requestingContainer) {
+ boolean onDescendantOrientationChanged(@Nullable WindowContainer requestingContainer) {
// If this is set to ignore the orientation request, we don't propagate descendant
// orientation request.
- return !getIgnoreOrientationRequest()
+ final int orientation = requestingContainer != null
+ ? requestingContainer.mOrientation : SCREEN_ORIENTATION_UNSET;
+ return !getIgnoreOrientationRequest(orientation)
&& super.onDescendantOrientationChanged(requestingContainer);
}
@@ -224,6 +230,23 @@
}
}
+ /**
+ * @return {@value true} if we need to ignore the orientation in input.
+ */
+ // TODO(b/262366204): Rename getIgnoreOrientationRequest to shouldIgnoreOrientationRequest
+ boolean getIgnoreOrientationRequest(@ScreenOrientation int orientation) {
+ // We always respect orientation request for ActivityInfo.SCREEN_ORIENTATION_LOCKED
+ // ActivityInfo.SCREEN_ORIENTATION_NOSENSOR.
+ // Main use case why this is important is Camera apps that rely on those
+ // properties to ensure that they will be able to determine Camera preview
+ // orientation correctly
+ if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
+ return false;
+ }
+ return getIgnoreOrientationRequest();
+ }
+
boolean getIgnoreOrientationRequest() {
// Adding an exception for when ignoreOrientationRequest is overridden at runtime for all
// DisplayArea-s. For example, this is needed for the Kids Mode since many Kids apps aren't
@@ -640,11 +663,9 @@
}
@Override
+ @ScreenOrientation
int getOrientation(int candidate) {
mLastOrientationSource = null;
- if (getIgnoreOrientationRequest()) {
- return SCREEN_ORIENTATION_UNSET;
- }
// Find a window requesting orientation.
final WindowState win = getWindow(mGetOrientingWindow);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5d502f5..4c49986 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1558,13 +1558,15 @@
}
@Override
- boolean onDescendantOrientationChanged(WindowContainer requestingContainer) {
+ boolean onDescendantOrientationChanged(@Nullable WindowContainer requestingContainer) {
final Configuration config = updateOrientation(
requestingContainer, false /* forceUpdate */);
// If display rotation class tells us that it doesn't consider app requested orientation,
// this display won't rotate just because of an app changes its requested orientation. Thus
// it indicates that this display chooses not to handle this request.
- final boolean handled = handlesOrientationChangeFromDescendant();
+ final int orientation = requestingContainer != null ? requestingContainer.mOrientation
+ : SCREEN_ORIENTATION_UNSET;
+ final boolean handled = handlesOrientationChangeFromDescendant(orientation);
if (config == null) {
return handled;
}
@@ -1587,8 +1589,8 @@
}
@Override
- boolean handlesOrientationChangeFromDescendant() {
- return !getIgnoreOrientationRequest()
+ boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
+ return !getIgnoreOrientationRequest(orientation)
&& !getDisplayRotation().isFixedToUserRotation();
}
@@ -1689,7 +1691,7 @@
return ROTATION_UNDEFINED;
}
if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM
- || getIgnoreOrientationRequest()) {
+ || getIgnoreOrientationRequest(r.mOrientation)) {
return ROTATION_UNDEFINED;
}
if (r.mOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
@@ -2688,15 +2690,6 @@
@ScreenOrientation
@Override
int getOrientation() {
- mLastOrientationSource = null;
- if (!handlesOrientationChangeFromDescendant()) {
- // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
- ProtoLog.v(WM_DEBUG_ORIENTATION,
- "Display id=%d is ignoring all orientation requests, return %d",
- mDisplayId, SCREEN_ORIENTATION_UNSPECIFIED);
- return SCREEN_ORIENTATION_UNSPECIFIED;
- }
-
if (mWmService.mDisplayFrozen) {
if (mWmService.mPolicy.isKeyguardLocked()) {
// Use the last orientation the while the display is frozen with the keyguard
@@ -2712,6 +2705,16 @@
}
final int orientation = super.getOrientation();
+
+ if (!handlesOrientationChangeFromDescendant(orientation)) {
+ mLastOrientationSource = null;
+ // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Display id=%d is ignoring orientation request for %d, return %d",
+ mDisplayId, orientation, SCREEN_ORIENTATION_UNSPECIFIED);
+ return SCREEN_ORIENTATION_UNSPECIFIED;
+ }
+
if (orientation == SCREEN_ORIENTATION_UNSET) {
// Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -3832,18 +3835,7 @@
/** Called when the focused {@link TaskDisplayArea} on this display may have changed. */
void onLastFocusedTaskDisplayAreaChanged(@Nullable TaskDisplayArea taskDisplayArea) {
- // Only record the TaskDisplayArea that handles orientation request.
- if (taskDisplayArea != null && taskDisplayArea.handlesOrientationChangeFromDescendant()) {
- mOrientationRequestingTaskDisplayArea = taskDisplayArea;
- return;
- }
-
- // If the previous TDA no longer handles orientation request, clear it.
- if (mOrientationRequestingTaskDisplayArea != null
- && !mOrientationRequestingTaskDisplayArea
- .handlesOrientationChangeFromDescendant()) {
- mOrientationRequestingTaskDisplayArea = null;
- }
+ mOrientationRequestingTaskDisplayArea = taskDisplayArea;
}
/**
@@ -5053,13 +5045,10 @@
}
@Override
- int getOrientation(int candidate) {
- if (getIgnoreOrientationRequest()) {
- return SCREEN_ORIENTATION_UNSET;
- }
-
+ @ScreenOrientation
+ int getOrientation(@ScreenOrientation int candidate) {
// IME does not participate in orientation.
- return candidate;
+ return getIgnoreOrientationRequest(candidate) ? SCREEN_ORIENTATION_UNSET : candidate;
}
@Override
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index bd83794..dde89e9 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -28,7 +28,7 @@
/** Helper class to ensure activities are in the right visible state for a container. */
class EnsureActivitiesVisibleHelper {
private final TaskFragment mTaskFragment;
- private ActivityRecord mTop;
+ private ActivityRecord mTopRunningActivity;
private ActivityRecord mStarting;
private boolean mAboveTop;
private boolean mContainerShouldBeVisible;
@@ -54,10 +54,10 @@
void reset(ActivityRecord starting, int configChanges, boolean preserveWindows,
boolean notifyClients) {
mStarting = starting;
- mTop = mTaskFragment.topRunningActivity();
+ mTopRunningActivity = mTaskFragment.topRunningActivity();
// If the top activity is not fullscreen, then we need to make sure any activities under it
// are now visible.
- mAboveTop = mTop != null;
+ mAboveTop = mTopRunningActivity != null;
mContainerShouldBeVisible = mTaskFragment.shouldBeVisible(mStarting);
mBehindFullyOccludedContainer = !mContainerShouldBeVisible;
mConfigChanges = configChanges;
@@ -85,18 +85,19 @@
reset(starting, configChanges, preserveWindows, notifyClients);
if (DEBUG_VISIBILITY) {
- Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + mTop
+ Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + mTopRunningActivity
+ " configChanges=0x" + Integer.toHexString(configChanges));
}
- if (mTop != null && mTaskFragment.asTask() != null) {
+ if (mTopRunningActivity != null && mTaskFragment.asTask() != null) {
// TODO(14709632): Check if this needed to be implemented in TaskFragment.
- mTaskFragment.asTask().checkTranslucentActivityWaiting(mTop);
+ mTaskFragment.asTask().checkTranslucentActivityWaiting(mTopRunningActivity);
}
// We should not resume activities that being launched behind because these
// activities are actually behind other fullscreen activities, but still required
// to be visible (such as performing Recents animation).
- final boolean resumeTopActivity = mTop != null && !mTop.mLaunchTaskBehind
+ final boolean resumeTopActivity = mTopRunningActivity != null
+ && !mTopRunningActivity.mLaunchTaskBehind
&& mTaskFragment.canBeResumed(starting)
&& (starting == null || !starting.isDescendantOf(mTaskFragment));
@@ -113,7 +114,7 @@
mBehindFullyOccludedContainer |=
(childTaskFragment.getBounds().equals(mTaskFragment.getBounds())
&& !childTaskFragment.isTranslucent(starting));
- if (mAboveTop && mTop.getTaskFragment() == childTaskFragment) {
+ if (mAboveTop && mTopRunningActivity.getTaskFragment() == childTaskFragment) {
mAboveTop = false;
}
@@ -147,8 +148,11 @@
private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
final boolean resumeTopActivity) {
- final boolean isTop = r == mTop;
+ final boolean isTop = r == mTopRunningActivity;
if (mAboveTop && !isTop) {
+ // Ensure activities above the top-running activity to be invisible because the
+ // activity should be finishing or cannot show to current user.
+ r.makeInvisible();
return;
}
mAboveTop = false;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 292ed95..ea6f244 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -143,6 +143,7 @@
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -2686,8 +2687,8 @@
}
@Override
- boolean handlesOrientationChangeFromDescendant() {
- if (!super.handlesOrientationChangeFromDescendant()) {
+ boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
+ if (!super.handlesOrientationChangeFromDescendant(orientation)) {
return false;
}
@@ -2702,7 +2703,7 @@
// Check for leaf Task.
// Display won't rotate for the orientation request if the Task/TaskDisplayArea
// can't specify orientation.
- return canSpecifyOrientation() && getDisplayArea().canSpecifyOrientation();
+ return canSpecifyOrientation() && getDisplayArea().canSpecifyOrientation(orientation);
}
void resize(boolean relayout, boolean forced) {
@@ -2772,6 +2773,13 @@
@Override
void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
Rect outSurfaceInsets) {
+ // If this task has its adjacent task, it means they should animate together. Use display
+ // bounds for them could move same as full screen task.
+ if (getAdjacentTaskFragment() != null && getAdjacentTaskFragment().asTask() != null) {
+ super.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
+ return;
+ }
+
final WindowState windowState = getTopVisibleAppMainWindow();
if (windowState != null) {
windowState.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
@@ -4920,6 +4928,11 @@
}
if (child.getVisibility(null /* starting */)
!= TASK_FRAGMENT_VISIBILITY_VISIBLE) {
+ if (child.topRunningActivity() == null) {
+ // Skip the task if no running activity and continue resuming next task.
+ continue;
+ }
+ // Otherwise, assuming everything behind this task should also be invisible.
break;
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index e0ed356..8ad76a3 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -41,6 +41,7 @@
import android.app.ActivityOptions;
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.UserHandle;
@@ -633,22 +634,20 @@
}
@Override
- int getOrientation(int candidate) {
- mLastOrientationSource = null;
- if (getIgnoreOrientationRequest()) {
- return SCREEN_ORIENTATION_UNSET;
- }
- if (!canSpecifyOrientation()) {
+ @ScreenOrientation
+ int getOrientation(@ScreenOrientation int candidate) {
+ final int orientation = super.getOrientation(candidate);
+ if (!canSpecifyOrientation(orientation)) {
+ mLastOrientationSource = null;
// We only respect orientation of the focused TDA, which can be a child of this TDA.
- return reduceOnAllTaskDisplayAreas((taskDisplayArea, orientation) -> {
- if (taskDisplayArea == this || orientation != SCREEN_ORIENTATION_UNSET) {
- return orientation;
+ return reduceOnAllTaskDisplayAreas((taskDisplayArea, taskOrientation) -> {
+ if (taskDisplayArea == this || taskOrientation != SCREEN_ORIENTATION_UNSET) {
+ return taskOrientation;
}
return taskDisplayArea.getOrientation(candidate);
}, SCREEN_ORIENTATION_UNSET);
}
- final int orientation = super.getOrientation(candidate);
if (orientation != SCREEN_ORIENTATION_UNSET
&& orientation != SCREEN_ORIENTATION_BEHIND) {
ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -1870,12 +1869,11 @@
}
/** Whether this task display area can request orientation. */
- boolean canSpecifyOrientation() {
- // Only allow to specify orientation if this TDA is not set to ignore orientation request,
- // and it is the last focused one on this logical display that can request orientation
- // request.
- return !getIgnoreOrientationRequest()
- && mDisplayContent.getOrientationRequestingTaskDisplayArea() == this;
+ boolean canSpecifyOrientation(@ScreenOrientation int orientation) {
+ // Only allow to specify orientation if this TDA is the last focused one on this logical
+ // display that can request orientation request.
+ return mDisplayContent.getOrientationRequestingTaskDisplayArea() == this
+ && !getIgnoreOrientationRequest(orientation);
}
void clearPreferredTopFocusableRootTask() {
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index ae4f894..f6db3f7 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -227,11 +227,16 @@
private TaskFragment mCompanionTaskFragment;
/**
- * Prevents duplicate calls to onTaskAppeared.
+ * Prevents duplicate calls to onTaskFragmentAppeared.
*/
boolean mTaskFragmentAppearedSent;
/**
+ * Prevents unnecessary callbacks after onTaskFragmentVanished.
+ */
+ boolean mTaskFragmentVanishedSent;
+
+ /**
* The last running activity of the TaskFragment was finished due to clear task while launching
* an activity in the Task.
*/
@@ -2223,7 +2228,8 @@
// task, because they should not be affected by insets.
inOutConfig.smallestScreenWidthDp = (int) (0.5f
+ Math.min(mTmpFullBounds.width(), mTmpFullBounds.height()) / density);
- } else if (isEmbedded()) {
+ } else if (windowingMode == WINDOWING_MODE_MULTI_WINDOW
+ && isEmbeddedWithBoundsOverride()) {
// For embedded TFs, the smallest width should be updated. Otherwise, inherit
// from the parent task would result in applications loaded wrong resource.
inOutConfig.smallestScreenWidthDp =
@@ -2552,7 +2558,7 @@
mRemoteToken.toWindowContainerToken(),
getConfiguration(),
getNonFinishingActivityCount(),
- isVisibleRequested(),
+ shouldBeVisible(null /* starting */),
childActivities,
positionInParent,
mClearedTaskForReuse,
@@ -2848,6 +2854,8 @@
if (parentTf != null) {
parentTf.onActivityVisibleRequestedChanged();
}
+ // Send the info changed to update the TaskFragment visibility.
+ sendTaskFragmentInfoChanged();
}
@Nullable
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 6e4df79..90a0dff 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -553,6 +553,9 @@
void onTaskFragmentAppeared(@NonNull ITaskFragmentOrganizer organizer,
@NonNull TaskFragment taskFragment) {
+ if (taskFragment.mTaskFragmentVanishedSent) {
+ return;
+ }
if (taskFragment.getTask() == null) {
Slog.w(TAG, "onTaskFragmentAppeared failed because it is not attached tf="
+ taskFragment);
@@ -574,6 +577,9 @@
void onTaskFragmentInfoChanged(@NonNull ITaskFragmentOrganizer organizer,
@NonNull TaskFragment taskFragment) {
+ if (taskFragment.mTaskFragmentVanishedSent) {
+ return;
+ }
validateAndGetState(organizer);
if (!taskFragment.mTaskFragmentAppearedSent) {
// Skip if TaskFragment still not appeared.
@@ -586,10 +592,6 @@
.setTaskFragment(taskFragment)
.build();
} else {
- if (pendingEvent.mEventType == PendingTaskFragmentEvent.EVENT_VANISHED) {
- // Skipped the info changed event if vanished event is pending.
- return;
- }
// Remove and add for re-ordering.
removePendingEvent(pendingEvent);
// Reset the defer time when TaskFragment is changed, so that it can check again if
@@ -602,6 +604,10 @@
void onTaskFragmentVanished(@NonNull ITaskFragmentOrganizer organizer,
@NonNull TaskFragment taskFragment) {
+ if (taskFragment.mTaskFragmentVanishedSent) {
+ return;
+ }
+ taskFragment.mTaskFragmentVanishedSent = true;
final TaskFragmentOrganizerState state = validateAndGetState(organizer);
final List<PendingTaskFragmentEvent> pendingEvents = mPendingTaskFragmentEvents
.get(organizer.asBinder());
@@ -617,20 +623,18 @@
.setTaskFragment(taskFragment)
.build());
state.removeTaskFragment(taskFragment);
+ // Make sure the vanished event will be dispatched if there are no other changes.
+ mAtmService.mWindowManager.mWindowPlacerLocked.requestTraversal();
}
void onTaskFragmentError(@NonNull ITaskFragmentOrganizer organizer,
@Nullable IBinder errorCallbackToken, @Nullable TaskFragment taskFragment,
int opType, @NonNull Throwable exception) {
- validateAndGetState(organizer);
- Slog.w(TAG, "onTaskFragmentError ", exception);
- final PendingTaskFragmentEvent vanishedEvent = taskFragment != null
- ? getPendingTaskFragmentEvent(taskFragment, PendingTaskFragmentEvent.EVENT_VANISHED)
- : null;
- if (vanishedEvent != null) {
- // No need to notify if the TaskFragment has been removed.
+ if (taskFragment != null && taskFragment.mTaskFragmentVanishedSent) {
return;
}
+ validateAndGetState(organizer);
+ Slog.w(TAG, "onTaskFragmentError ", exception);
addPendingEvent(new PendingTaskFragmentEvent.Builder(
PendingTaskFragmentEvent.EVENT_ERROR, organizer)
.setErrorCallbackToken(errorCallbackToken)
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 5c893de..cb5a433 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -18,6 +18,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -1419,9 +1420,9 @@
* @return {@code true} if it handles or will handle orientation change in the future; {@code
* false} if it won't handle the change at anytime.
*/
- boolean handlesOrientationChangeFromDescendant() {
+ boolean handlesOrientationChangeFromDescendant(int orientation) {
final WindowContainer parent = getParent();
- return parent != null && parent.handlesOrientationChangeFromDescendant();
+ return parent != null && parent.handlesOrientationChangeFromDescendant(orientation);
}
/**
@@ -1513,7 +1514,8 @@
// portrait but the task is still in landscape. While updating from display,
// the task can be updated to portrait first so the configuration can be
// computed in a consistent environment.
- && (inMultiWindowMode() || !handlesOrientationChangeFromDescendant())) {
+ && (inMultiWindowMode()
+ || !handlesOrientationChangeFromDescendant(orientation))) {
// Resolve the requested orientation.
onConfigurationChanged(parent.getConfiguration());
}
@@ -3186,7 +3188,8 @@
if (isOrganized()
// TODO(b/161711458): Clean-up when moved to shell.
&& getWindowingMode() != WINDOWING_MODE_FULLSCREEN
- && getWindowingMode() != WINDOWING_MODE_FREEFORM) {
+ && getWindowingMode() != WINDOWING_MODE_FREEFORM
+ && getWindowingMode() != WINDOWING_MODE_MULTI_WINDOW) {
return null;
}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index cd77709..eba3ea4 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -1062,7 +1062,7 @@
if (activity == null || activity.finishing) {
break;
}
- if (activity.isVisible()) {
+ if (activity.isVisible() || activity.isVisibleRequested()) {
// Prevent the transition from being executed too early if the activity is
// visible.
activity.finishIfPossible("finish-activity-op", false /* oomAdj */);
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index f53a1cf..f628fba 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -44,9 +44,11 @@
</xs:element>
<xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0"
maxOccurs="1"/>
- <xs:element type="displayQuirks" name="quirks" minOccurs="0" maxOccurs="1" />
+ <xs:element type="displayQuirks" name="quirks" minOccurs="0" maxOccurs="1"/>
<xs:element type="autoBrightness" name="autoBrightness" minOccurs="0"
- maxOccurs="1" />
+ maxOccurs="1"/>
+ <xs:element type="refreshRateConfigs" name="refreshRate" minOccurs="0"
+ maxOccurs="1"/>
<xs:element type="nonNegativeDecimal" name="screenBrightnessRampFastDecrease">
<xs:annotation name="final"/>
</xs:element>
@@ -72,6 +74,9 @@
<xs:element type="sensorDetails" name="lightSensor">
<xs:annotation name="final"/>
</xs:element>
+ <xs:element type="sensorDetails" name="screenOffBrightnessSensor">
+ <xs:annotation name="final"/>
+ </xs:element>
<xs:element type="sensorDetails" name="proxSensor">
<xs:annotation name="final"/>
</xs:element>
@@ -107,6 +112,11 @@
<xs:element type="thresholds" name="ambientBrightnessChangeThresholdsIdle" minOccurs="0" maxOccurs="1">
<xs:annotation name="final"/>
</xs:element>
+ <!-- Table that translates sensor values from the screenOffBrightnessSensor
+ to lux values; -1 means the lux reading is not available. -->
+ <xs:element type="integer-array" name="screenOffBrightnessSensorValueToLux">
+ <xs:annotation name="final"/>
+ </xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
@@ -324,7 +334,7 @@
<xs:annotation name="final"/>
</xs:element>
</xs:sequence>
- </xs:complexType>
+ </xs:complexType>
<!-- Thresholds for brightness changes. -->
<xs:complexType name="thresholds">
@@ -452,4 +462,41 @@
</xs:element>
</xs:sequence>
</xs:complexType>
+
+ <xs:complexType name="refreshRateConfigs">
+ <xs:element name="lowerBlockingZoneConfigs" type="blockingZoneConfig"
+ minOccurs="0" maxOccurs="1">
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element name="higherBlockingZoneConfigs" type="blockingZoneConfig"
+ minOccurs="0" maxOccurs="1">
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:complexType>
+
+ <xs:complexType name="blockingZoneConfig">
+ <xs:element name="defaultRefreshRate" type="xs:nonNegativeInteger"
+ minOccurs="1" maxOccurs="1">
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element name="blockingZoneThreshold" type="blockingZoneThreshold"
+ minOccurs="1" maxOccurs="1">
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:complexType>
+
+ <xs:complexType name="blockingZoneThreshold">
+ <xs:sequence>
+ <xs:element name="displayBrightnessPoint" type="displayBrightnessPoint"
+ minOccurs="1" maxOccurs="unbounded">
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="integer-array">
+ <xs:sequence>
+ <xs:element name="item" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
</xs:schema>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index d89bd7c..cb08179 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -13,6 +13,19 @@
method public void setEnabled(boolean);
}
+ public class BlockingZoneConfig {
+ ctor public BlockingZoneConfig();
+ method public final com.android.server.display.config.BlockingZoneThreshold getBlockingZoneThreshold();
+ method public final java.math.BigInteger getDefaultRefreshRate();
+ method public final void setBlockingZoneThreshold(com.android.server.display.config.BlockingZoneThreshold);
+ method public final void setDefaultRefreshRate(java.math.BigInteger);
+ }
+
+ public class BlockingZoneThreshold {
+ ctor public BlockingZoneThreshold();
+ method public final java.util.List<com.android.server.display.config.DisplayBrightnessPoint> getDisplayBrightnessPoint();
+ }
+
public class BrightnessThresholds {
ctor public BrightnessThresholds();
method public final com.android.server.display.config.ThresholdPoints getBrightnessThresholdPoints();
@@ -76,6 +89,7 @@
method public final com.android.server.display.config.SensorDetails getLightSensor();
method public final com.android.server.display.config.SensorDetails getProxSensor();
method public com.android.server.display.config.DisplayQuirks getQuirks();
+ method public com.android.server.display.config.RefreshRateConfigs getRefreshRate();
method @NonNull public final java.math.BigDecimal getScreenBrightnessDefault();
method @NonNull public final com.android.server.display.config.NitsMap getScreenBrightnessMap();
method public final java.math.BigInteger getScreenBrightnessRampDecreaseMaxMillis();
@@ -84,6 +98,8 @@
method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis();
method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
+ method public final com.android.server.display.config.SensorDetails getScreenOffBrightnessSensor();
+ method public final com.android.server.display.config.IntegerArray getScreenOffBrightnessSensorValueToLux();
method @NonNull public final com.android.server.display.config.ThermalThrottling getThermalThrottling();
method public final void setAmbientBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds);
method public final void setAmbientBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds);
@@ -97,6 +113,7 @@
method public final void setLightSensor(com.android.server.display.config.SensorDetails);
method public final void setProxSensor(com.android.server.display.config.SensorDetails);
method public void setQuirks(com.android.server.display.config.DisplayQuirks);
+ method public void setRefreshRate(com.android.server.display.config.RefreshRateConfigs);
method public final void setScreenBrightnessDefault(@NonNull java.math.BigDecimal);
method public final void setScreenBrightnessMap(@NonNull com.android.server.display.config.NitsMap);
method public final void setScreenBrightnessRampDecreaseMaxMillis(java.math.BigInteger);
@@ -105,6 +122,8 @@
method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger);
method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal);
method public final void setScreenBrightnessRampSlowIncrease(java.math.BigDecimal);
+ method public final void setScreenOffBrightnessSensor(com.android.server.display.config.SensorDetails);
+ method public final void setScreenOffBrightnessSensorValueToLux(com.android.server.display.config.IntegerArray);
method public final void setThermalThrottling(@NonNull com.android.server.display.config.ThermalThrottling);
}
@@ -145,6 +164,11 @@
method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal);
}
+ public class IntegerArray {
+ ctor public IntegerArray();
+ method public java.util.List<java.math.BigInteger> getItem();
+ }
+
public class NitsMap {
ctor public NitsMap();
method public String getInterpolation();
@@ -160,6 +184,14 @@
method public final void setValue(@NonNull java.math.BigDecimal);
}
+ public class RefreshRateConfigs {
+ ctor public RefreshRateConfigs();
+ method public final com.android.server.display.config.BlockingZoneConfig getHigherBlockingZoneConfigs();
+ method public final com.android.server.display.config.BlockingZoneConfig getLowerBlockingZoneConfigs();
+ method public final void setHigherBlockingZoneConfigs(com.android.server.display.config.BlockingZoneConfig);
+ method public final void setLowerBlockingZoneConfigs(com.android.server.display.config.BlockingZoneConfig);
+ }
+
public class RefreshRateRange {
ctor public RefreshRateRange();
method public final java.math.BigInteger getMaximum();
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index ed369c0..82236bf 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -155,6 +155,18 @@
when(mMockedResources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels))
.thenReturn(new int[]{});
+ when(mMockedResources.getIntArray(
+ com.android.internal.R.array.config_brightnessThresholdsOfPeakRefreshRate))
+ .thenReturn(new int[]{});
+ when(mMockedResources.getIntArray(
+ com.android.internal.R.array.config_ambientThresholdsOfPeakRefreshRate))
+ .thenReturn(new int[]{});
+ when(mMockedResources.getIntArray(
+ com.android.internal.R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate))
+ .thenReturn(new int[]{});
+ when(mMockedResources.getIntArray(
+ com.android.internal.R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
+ .thenReturn(new int[]{});
}
@After
diff --git a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index bb08ef75..3834834 100644
--- a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.anyFloat;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -97,7 +98,8 @@
mLightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor");
mContext = InstrumentationRegistry.getContext();
- mController = setupController(mLightSensor);
+ mController = setupController(mLightSensor, BrightnessMappingStrategy.NO_USER_LUX,
+ BrightnessMappingStrategy.NO_USER_BRIGHTNESS);
}
@After
@@ -109,7 +111,8 @@
}
}
- private AutomaticBrightnessController setupController(Sensor lightSensor) {
+ private AutomaticBrightnessController setupController(Sensor lightSensor, float userLux,
+ float userBrightness) {
mClock = new OffsettableClock.Stopped();
mTestLooper = new TestLooper(mClock::now);
@@ -134,7 +137,7 @@
mAmbientBrightnessThresholds, mScreenBrightnessThresholds,
mAmbientBrightnessThresholdsIdle, mScreenBrightnessThresholdsIdle,
mContext, mHbmController, mBrightnessThrottler, mIdleBrightnessMappingStrategy,
- AMBIENT_LIGHT_HORIZON_SHORT, AMBIENT_LIGHT_HORIZON_LONG
+ AMBIENT_LIGHT_HORIZON_SHORT, AMBIENT_LIGHT_HORIZON_LONG, userLux, userBrightness
);
when(mHbmController.getCurrentBrightnessMax()).thenReturn(BRIGHTNESS_MAX_FLOAT);
@@ -145,9 +148,10 @@
// Configure the brightness controller and grab an instance of the sensor listener,
// through which we can deliver fake (for test) sensor values.
- controller.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
- 0 /* brightness */, false /* userChangedBrightness */, 0 /* adjustment */,
- false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
+ controller.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */,
+ 0 /* brightness= */, false /* userChangedBrightness= */, 0 /* adjustment= */,
+ false /* userChanged= */, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ true);
return controller;
}
@@ -252,9 +256,10 @@
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 1000));
// User sets brightness to 100
- mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
- 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */,
- false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
+ mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */,
+ 0.5f /* brightness= */, true /* userChangedBrightness= */, 0 /* adjustment= */,
+ false /* userChanged= */, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ true);
// There should be a user data point added to the mapper.
verify(mBrightnessMappingStrategy).addUserDataPoint(1000f, 0.5f);
@@ -274,9 +279,10 @@
// User sets brightness to 0.5f
when(mBrightnessMappingStrategy.getBrightness(currentLux,
null, ApplicationInfo.CATEGORY_UNDEFINED)).thenReturn(0.5f);
- mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
- 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */,
- false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
+ mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */,
+ 0.5f /* brightness= */, true /* userChangedBrightness= */, 0 /* adjustment= */,
+ false /* userChanged= */, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ true);
//Recalculating the spline with RBC enabled, verifying that the short term model is reset,
//and the interaction is learnt in short term model
@@ -307,9 +313,10 @@
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 1000));
// User sets brightness to 100
- mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
- 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */,
- false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
+ mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */,
+ 0.5f /* brightness= */, true /* userChangedBrightness= */, 0 /* adjustment= */,
+ false /* userChanged= */, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ true);
// There should be a user data point added to the mapper.
verify(mBrightnessMappingStrategy, times(1)).addUserDataPoint(1000f, 0.5f);
@@ -325,9 +332,10 @@
verifyNoMoreInteractions(mBrightnessMappingStrategy);
// User sets idle brightness to 0.5
- mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
- 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */,
- false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
+ mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */,
+ 0.5f /* brightness= */, true /* userChangedBrightness= */, 0 /* adjustment= */,
+ false /* userChanged= */, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ true);
// Ensure we use the correct mapping strategy
verify(mIdleBrightnessMappingStrategy, times(1)).addUserDataPoint(1000f, 0.5f);
@@ -483,17 +491,19 @@
final float throttledBrightness = 0.123f;
when(mBrightnessThrottler.getBrightnessCap()).thenReturn(throttledBrightness);
when(mBrightnessThrottler.isThrottled()).thenReturn(true);
- mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
- BRIGHTNESS_MAX_FLOAT /* brightness */, false /* userChangedBrightness */,
- 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
+ mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */,
+ BRIGHTNESS_MAX_FLOAT /* brightness= */, false /* userChangedBrightness= */,
+ 0 /* adjustment= */, false /* userChanged= */, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ true);
assertEquals(throttledBrightness, mController.getAutomaticScreenBrightness(), 0.0f);
// Remove throttling and notify ABC again
when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
when(mBrightnessThrottler.isThrottled()).thenReturn(false);
- mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
- BRIGHTNESS_MAX_FLOAT /* brightness */, false /* userChangedBrightness */,
- 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
+ mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */,
+ BRIGHTNESS_MAX_FLOAT /* brightness= */, false /* userChangedBrightness= */,
+ 0 /* adjustment= */, false /* userChanged= */, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ true);
assertEquals(BRIGHTNESS_MAX_FLOAT, mController.getAutomaticScreenBrightness(), 0.0f);
}
@@ -584,4 +594,32 @@
assertEquals(lux, sensorValues[0], EPSILON);
assertEquals(mClock.now() - AMBIENT_LIGHT_HORIZON_LONG, sensorTimestamps[0]);
}
+
+ @Test
+ public void testResetShortTermModelWhenConfigChanges() {
+ when(mBrightnessMappingStrategy.isForIdleMode()).thenReturn(false);
+ when(mBrightnessMappingStrategy.setBrightnessConfiguration(any())).thenReturn(true);
+
+ mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */,
+ BRIGHTNESS_MAX_FLOAT /* brightness= */, false /* userChangedBrightness= */,
+ 0 /* adjustment= */, false /* userChanged= */, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ false);
+ verify(mBrightnessMappingStrategy, never()).clearUserDataPoints();
+
+ mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */,
+ BRIGHTNESS_MAX_FLOAT /* brightness= */, false /* userChangedBrightness= */,
+ 0 /* adjustment= */, false /* userChanged= */, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ true);
+ verify(mBrightnessMappingStrategy).clearUserDataPoints();
+ }
+
+ @Test
+ public void testUseProvidedShortTermModel() {
+ verify(mBrightnessMappingStrategy, never()).addUserDataPoint(anyFloat(), anyFloat());
+
+ float userLux = 1000;
+ float userBrightness = 0.3f;
+ setupController(mLightSensor, userLux, userBrightness);
+ verify(mBrightnessMappingStrategy).addUserDataPoint(userLux, userBrightness);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 7f341ff..86c5937 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -150,6 +150,24 @@
assertEquals("ProximitySensor123", mDisplayDeviceConfig.getProximitySensor().name);
assertEquals("prox_type_1", mDisplayDeviceConfig.getProximitySensor().type);
+ assertEquals(75, mDisplayDeviceConfig.getDefaultLowRefreshRate());
+ assertEquals(90, mDisplayDeviceConfig.getDefaultHighRefreshRate());
+ assertArrayEquals(new int[]{45, 55},
+ mDisplayDeviceConfig.getLowDisplayBrightnessThresholds());
+ assertArrayEquals(new int[]{50, 60},
+ mDisplayDeviceConfig.getLowAmbientBrightnessThresholds());
+ assertArrayEquals(new int[]{65, 75},
+ mDisplayDeviceConfig.getHighDisplayBrightnessThresholds());
+ assertArrayEquals(new int[]{70, 80},
+ mDisplayDeviceConfig.getHighAmbientBrightnessThresholds());
+
+ assertEquals("sensor_12345",
+ mDisplayDeviceConfig.getScreenOffBrightnessSensor().type);
+ assertEquals("Sensor 12345",
+ mDisplayDeviceConfig.getScreenOffBrightnessSensor().name);
+
+ assertArrayEquals(new int[]{-1, 10, 20, 30, 40},
+ mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux());
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
@@ -212,9 +230,8 @@
mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle(), ZERO_DELTA);
assertArrayEquals(new float[]{29, 30, 31},
mDisplayDeviceConfig.getAmbientDarkeningPercentagesIdle(), ZERO_DELTA);
-
- assertEquals(mDisplayDeviceConfig.getDefaultRefreshRate(), DEFAULT_REFRESH_RATE);
- assertEquals(mDisplayDeviceConfig.getDefaultPeakRefreshRate(), DEFAULT_PEAK_REFRESH_RATE);
+ assertEquals(mDisplayDeviceConfig.getDefaultLowRefreshRate(), DEFAULT_REFRESH_RATE);
+ assertEquals(mDisplayDeviceConfig.getDefaultHighRefreshRate(), DEFAULT_PEAK_REFRESH_RATE);
assertArrayEquals(mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(),
LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
assertArrayEquals(mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(),
@@ -223,6 +240,7 @@
HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
assertArrayEquals(mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(),
HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
+
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
}
@@ -274,6 +292,10 @@
+ "<thermalStatusLimit>light</thermalStatusLimit>\n"
+ "<allowInLowPowerMode>false</allowInLowPowerMode>\n"
+ "</highBrightnessMode>\n"
+ + "<screenOffBrightnessSensor>\n"
+ + "<type>sensor_12345</type>\n"
+ + "<name>Sensor 12345</name>\n"
+ + "</screenOffBrightnessSensor>\n"
+ "<ambientBrightnessChangeThresholds>\n"
+ "<brighteningThresholds>\n"
+ "<minimum>10</minimum>\n"
@@ -426,6 +448,45 @@
+ "<name>ProximitySensor123</name>\n"
+ "<type>prox_type_1</type>\n"
+ "</proxSensor>\n"
+ + "<refreshRate>\n"
+ + "<lowerBlockingZoneConfigs>\n"
+ + "<defaultRefreshRate>75</defaultRefreshRate>\n"
+ + "<blockingZoneThreshold>\n"
+ + "<displayBrightnessPoint>\n"
+ + "<lux>50</lux>\n"
+ // This number will be rounded to integer when read by the system
+ + "<nits>45.3</nits>\n"
+ + "</displayBrightnessPoint>\n"
+ + "<displayBrightnessPoint>\n"
+ + "<lux>60</lux>\n"
+ // This number will be rounded to integer when read by the system
+ + "<nits>55.2</nits>\n"
+ + "</displayBrightnessPoint>\n"
+ + "</blockingZoneThreshold>\n"
+ + "</lowerBlockingZoneConfigs>\n"
+ + "<higherBlockingZoneConfigs>\n"
+ + "<defaultRefreshRate>90</defaultRefreshRate>\n"
+ + "<blockingZoneThreshold>\n"
+ + "<displayBrightnessPoint>\n"
+ + "<lux>70</lux>\n"
+ // This number will be rounded to integer when read by the system
+ + "<nits>65.6</nits>\n"
+ + "</displayBrightnessPoint>\n"
+ + "<displayBrightnessPoint>\n"
+ + "<lux>80</lux>\n"
+ // This number will be rounded to integer when read by the system
+ + "<nits>75</nits>\n"
+ + "</displayBrightnessPoint>\n"
+ + "</blockingZoneThreshold>\n"
+ + "</higherBlockingZoneConfigs>\n"
+ + "</refreshRate>\n"
+ + "<screenOffBrightnessSensorValueToLux>\n"
+ + "<item>-1</item>\n"
+ + "<item>10</item>\n"
+ + "<item>20</item>\n"
+ + "<item>30</item>\n"
+ + "<item>40</item>\n"
+ + "</screenOffBrightnessSensorValueToLux>\n"
+ "</displayConfiguration>\n";
}
@@ -503,6 +564,7 @@
when(mResources.getIntArray(
R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
.thenReturn(HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
+
mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
}
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index fb0cdfa..cfea63b 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -1896,8 +1896,8 @@
// Notify that the default display is updated, such that DisplayDeviceConfig has new values
DisplayDeviceConfig displayDeviceConfig = mock(DisplayDeviceConfig.class);
- when(displayDeviceConfig.getDefaultRefreshRate()).thenReturn(50);
- when(displayDeviceConfig.getDefaultPeakRefreshRate()).thenReturn(55);
+ when(displayDeviceConfig.getDefaultLowRefreshRate()).thenReturn(50);
+ when(displayDeviceConfig.getDefaultHighRefreshRate()).thenReturn(55);
when(displayDeviceConfig.getLowDisplayBrightnessThresholds()).thenReturn(new int[]{25});
when(displayDeviceConfig.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30});
when(displayDeviceConfig.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210});
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
index d515fae..638637d 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -18,10 +18,14 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.DEFAULT_DISPLAY_GROUP;
+import static android.view.Display.TYPE_INTERNAL;
+import static android.view.Display.TYPE_VIRTUAL;
+import static com.android.server.display.DeviceStateToLayoutMap.STATE_DEFAULT;
import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED;
import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED;
import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED;
+import static com.android.server.display.DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY;
import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED;
import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED;
@@ -69,7 +73,6 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
-import java.util.Set;
@SmallTest
@Presubmit
@@ -151,8 +154,8 @@
@Test
public void testDisplayDeviceAddAndRemove_Internal() {
- DisplayDevice device = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ DisplayDevice device = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
// add
LogicalDisplay displayAdded = add(device);
@@ -173,7 +176,7 @@
testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_EXTERNAL);
testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_WIFI);
testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_OVERLAY);
- testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_VIRTUAL);
+ testDisplayDeviceAddAndRemove_NonInternal(TYPE_VIRTUAL);
testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_UNKNOWN);
// Call the internal test again, just to verify that adding non-internal displays
@@ -183,9 +186,9 @@
@Test
public void testDisplayDeviceAdd_TwoInternalOneDefault() {
- DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0);
- DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, 0);
+ DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
LogicalDisplay display1 = add(device1);
assertEquals(info(display1).address, info(device1).address);
@@ -198,10 +201,10 @@
@Test
public void testDisplayDeviceAdd_TwoInternalBothDefault() {
- DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
- DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
LogicalDisplay display1 = add(device1);
assertEquals(info(display1).address, info(device1).address);
@@ -216,7 +219,7 @@
@Test
public void testDisplayDeviceAddAndRemove_OneExternalDefault() {
DisplayDevice device = createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
// add
LogicalDisplay displayAdded = add(device);
@@ -234,10 +237,10 @@
@Test
public void testDisplayDeviceAddAndRemove_SwitchDefault() {
- DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
- DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
LogicalDisplay display1 = add(device1);
assertEquals(info(display1).address, info(device1).address);
@@ -263,10 +266,10 @@
@Test
public void testGetDisplayIdsLocked() {
- add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
+ add(createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800, 0));
- add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0));
+ add(createDisplayDevice(TYPE_VIRTUAL, 600, 800, 0));
int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID,
/* includeDisabled= */ true);
@@ -276,71 +279,98 @@
}
@Test
- public void testGetDisplayInfoForStateLocked_oneDisplayGroup_internalType() {
- add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
- add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
- add(createDisplayDevice(Display.TYPE_INTERNAL, 700, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
+ public void testGetDisplayInfoForStateLocked_defaultLayout() {
+ final DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ final DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 200, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
- Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
- DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfos.size()).isEqualTo(1);
- for (DisplayInfo displayInfo : displayInfos) {
- assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY);
- assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfo.logicalWidth).isEqualTo(600);
- assertThat(displayInfo.logicalHeight).isEqualTo(800);
- }
+ add(device1);
+ add(device2);
+
+ Layout layout1 = new Layout();
+ layout1.createDisplayLocked(info(device1).address, /* isDefault= */ true,
+ /* isEnabled= */ true);
+ layout1.createDisplayLocked(info(device2).address, /* isDefault= */ false,
+ /* isEnabled= */ true);
+ when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout1);
+ assertThat(layout1.size()).isEqualTo(2);
+ final int logicalId2 = layout1.getByAddress(info(device2).address).getLogicalDisplayId();
+
+ final DisplayInfo displayInfoDefault = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
+ STATE_DEFAULT, DEFAULT_DISPLAY);
+ assertThat(displayInfoDefault.displayId).isEqualTo(DEFAULT_DISPLAY);
+ assertThat(displayInfoDefault.logicalWidth).isEqualTo(width(device1));
+ assertThat(displayInfoDefault.logicalHeight).isEqualTo(height(device1));
+
+ final DisplayInfo displayInfoOther = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
+ STATE_DEFAULT, logicalId2);
+ assertThat(displayInfoOther).isNotNull();
+ assertThat(displayInfoOther.displayId).isEqualTo(logicalId2);
+ assertThat(displayInfoOther.logicalWidth).isEqualTo(width(device2));
+ assertThat(displayInfoOther.logicalHeight).isEqualTo(height(device2));
}
@Test
- public void testGetDisplayInfoForStateLocked_oneDisplayGroup_differentTypes() {
- add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
- add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
- add(createDisplayDevice(Display.TYPE_EXTERNAL, 700, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
+ public void testGetDisplayInfoForStateLocked_multipleLayouts() {
+ final DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ final DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 200, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ final DisplayDevice device3 = createDisplayDevice(TYPE_VIRTUAL, 700, 800,
+ DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
- Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
- DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfos.size()).isEqualTo(1);
- for (DisplayInfo displayInfo : displayInfos) {
- assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY);
- assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfo.logicalWidth).isEqualTo(600);
- assertThat(displayInfo.logicalHeight).isEqualTo(800);
- }
- }
+ add(device1);
+ add(device2);
+ add(device3);
- @Test
- public void testGetDisplayInfoForStateLocked_multipleDisplayGroups_defaultGroup() {
- add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
- add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
- add(createDisplayDevice(Display.TYPE_VIRTUAL, 700, 800,
- DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP));
+ Layout layout1 = new Layout();
+ layout1.createDisplayLocked(info(device1).address,
+ /* isDefault= */ true, /* isEnabled= */ true);
+ when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout1);
- Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
- DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfos.size()).isEqualTo(1);
- for (DisplayInfo displayInfo : displayInfos) {
- assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY);
- assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfo.logicalWidth).isEqualTo(600);
- assertThat(displayInfo.logicalHeight).isEqualTo(800);
- }
+ final int layoutState2 = 2;
+ Layout layout2 = new Layout();
+ layout2.createDisplayLocked(info(device2).address,
+ /* isDefault= */ false, /* isEnabled= */ true);
+ // Device3 is the default display.
+ layout2.createDisplayLocked(info(device3).address,
+ /* isDefault= */ true, /* isEnabled= */ true);
+ when(mDeviceStateToLayoutMapSpy.get(layoutState2)).thenReturn(layout2);
+ assertThat(layout2.size()).isEqualTo(2);
+ final int logicalId2 = layout2.getByAddress(info(device2).address).getLogicalDisplayId();
+
+ // Default layout.
+ final DisplayInfo displayInfoLayout1Default =
+ mLogicalDisplayMapper.getDisplayInfoForStateLocked(
+ STATE_DEFAULT, DEFAULT_DISPLAY);
+ assertThat(displayInfoLayout1Default.displayId).isEqualTo(DEFAULT_DISPLAY);
+ assertThat(displayInfoLayout1Default.logicalWidth).isEqualTo(width(device1));
+ assertThat(displayInfoLayout1Default.logicalHeight).isEqualTo(height(device1));
+
+ // Second layout, where device3 is the default display.
+ final DisplayInfo displayInfoLayout2Default =
+ mLogicalDisplayMapper.getDisplayInfoForStateLocked(
+ layoutState2, DEFAULT_DISPLAY);
+ assertThat(displayInfoLayout2Default.displayId).isEqualTo(DEFAULT_DISPLAY);
+ assertThat(displayInfoLayout2Default.logicalWidth).isEqualTo(width(device3));
+ assertThat(displayInfoLayout2Default.logicalHeight).isEqualTo(height(device3));
+
+ final DisplayInfo displayInfoLayout2Other =
+ mLogicalDisplayMapper.getDisplayInfoForStateLocked(
+ layoutState2, logicalId2);
+ assertThat(displayInfoLayout2Other).isNotNull();
+ assertThat(displayInfoLayout2Other.displayId).isEqualTo(logicalId2);
+ assertThat(displayInfoLayout2Other.logicalWidth).isEqualTo(width(device2));
+ assertThat(displayInfoLayout2Other.logicalHeight).isEqualTo(height(device2));
}
@Test
public void testSingleDisplayGroup() {
- LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
- LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0));
- LogicalDisplay display3 = add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0));
+ LogicalDisplay display1 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
+ LogicalDisplay display2 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800, 0));
+ LogicalDisplay display3 = add(createDisplayDevice(TYPE_VIRTUAL, 600, 800, 0));
assertEquals(DEFAULT_DISPLAY_GROUP,
mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display1)));
@@ -352,12 +382,12 @@
@Test
public void testMultipleDisplayGroups() {
- LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
- LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0));
+ LogicalDisplay display1 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
+ LogicalDisplay display2 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800, 0));
- TestDisplayDevice device3 = createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800,
+ TestDisplayDevice device3 = createDisplayDevice(TYPE_VIRTUAL, 600, 800,
DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
LogicalDisplay display3 = add(device3);
@@ -423,10 +453,10 @@
@Test
public void testDeviceStateLocked() {
- DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
- DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
Layout layout = new Layout();
layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address, true, true);
@@ -479,13 +509,13 @@
DisplayAddress displayAddressTwo = new TestUtils.TestDisplayAddress();
DisplayAddress displayAddressThree = new TestUtils.TestDisplayAddress();
- TestDisplayDevice device1 = createDisplayDevice(displayAddressOne, Display.TYPE_INTERNAL,
+ TestDisplayDevice device1 = createDisplayDevice(displayAddressOne, TYPE_INTERNAL,
600, 800,
- DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
- TestDisplayDevice device2 = createDisplayDevice(displayAddressTwo, Display.TYPE_INTERNAL,
+ FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ TestDisplayDevice device2 = createDisplayDevice(displayAddressTwo, TYPE_INTERNAL,
200, 800,
DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
- TestDisplayDevice device3 = createDisplayDevice(displayAddressThree, Display.TYPE_INTERNAL,
+ TestDisplayDevice device3 = createDisplayDevice(displayAddressThree, TYPE_INTERNAL,
600, 900, DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
Layout threeDevicesEnabledLayout = new Layout();
@@ -502,7 +532,7 @@
/* isDefault= */ false,
/* isEnabled= */ true);
- when(mDeviceStateToLayoutMapSpy.get(DeviceStateToLayoutMap.STATE_DEFAULT))
+ when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT))
.thenReturn(threeDevicesEnabledLayout);
LogicalDisplay display1 = add(device1);
@@ -620,6 +650,14 @@
return device.getDisplayDeviceInfoLocked();
}
+ private int width(DisplayDevice device) {
+ return info(device).width;
+ }
+
+ private int height(DisplayDevice device) {
+ return info(device).height;
+ }
+
private DisplayInfo info(LogicalDisplay display) {
return display.getDisplayInfoLocked();
}
diff --git a/services/tests/servicestests/src/com/android/server/display/ScreenOffBrightnessSensorControllerTest.java b/services/tests/servicestests/src/com/android/server/display/ScreenOffBrightnessSensorControllerTest.java
new file mode 100644
index 0000000..ea04a19
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/ScreenOffBrightnessSensorControllerTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.testutils.OffsettableClock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ScreenOffBrightnessSensorControllerTest {
+
+ private static final int[] SENSOR_TO_LUX = new int[]{-1, 10, 20, 30, 40};
+
+ private ScreenOffBrightnessSensorController mController;
+ private OffsettableClock mClock;
+ private Sensor mLightSensor;
+
+ @Mock SensorManager mSensorManager;
+ @Mock Handler mNoOpHandler;
+ @Mock BrightnessMappingStrategy mBrightnessMappingStrategy;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mClock = new OffsettableClock.Stopped();
+ mLightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor");
+ mController = new ScreenOffBrightnessSensorController(
+ mSensorManager,
+ mLightSensor,
+ mNoOpHandler,
+ mClock::now,
+ SENSOR_TO_LUX,
+ mBrightnessMappingStrategy
+ );
+ }
+
+ @Test
+ public void testBrightness() throws Exception {
+ when(mSensorManager.registerListener(any(SensorEventListener.class), eq(mLightSensor),
+ eq(SensorManager.SENSOR_DELAY_NORMAL), any(Handler.class)))
+ .thenReturn(true);
+ mController.setLightSensorEnabled(true);
+ ArgumentCaptor<SensorEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(SensorEventListener.class);
+ verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
+ eq(SensorManager.SENSOR_DELAY_NORMAL), any(Handler.class));
+ SensorEventListener listener = listenerCaptor.getValue();
+
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 0));
+ assertEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ mController.getAutomaticScreenBrightness(), 0);
+
+ int sensorValue = 1;
+ float brightness = 0.2f;
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
+ when(mBrightnessMappingStrategy.getBrightness(SENSOR_TO_LUX[sensorValue]))
+ .thenReturn(brightness);
+ assertEquals(brightness, mController.getAutomaticScreenBrightness(), 0);
+
+ sensorValue = 2;
+ brightness = 0.4f;
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
+ when(mBrightnessMappingStrategy.getBrightness(SENSOR_TO_LUX[sensorValue]))
+ .thenReturn(brightness);
+ assertEquals(brightness, mController.getAutomaticScreenBrightness(), 0);
+
+ sensorValue = 3;
+ brightness = 0.6f;
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
+ when(mBrightnessMappingStrategy.getBrightness(SENSOR_TO_LUX[sensorValue]))
+ .thenReturn(brightness);
+ assertEquals(brightness, mController.getAutomaticScreenBrightness(), 0);
+
+ sensorValue = 4;
+ brightness = 0.8f;
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
+ when(mBrightnessMappingStrategy.getBrightness(SENSOR_TO_LUX[sensorValue]))
+ .thenReturn(brightness);
+ assertEquals(brightness, mController.getAutomaticScreenBrightness(), 0);
+
+ sensorValue = 5;
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
+ assertEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ mController.getAutomaticScreenBrightness(), 0);
+ }
+
+ @Test
+ public void testSensorValueValidTime() throws Exception {
+ when(mSensorManager.registerListener(any(SensorEventListener.class), eq(mLightSensor),
+ eq(SensorManager.SENSOR_DELAY_NORMAL), any(Handler.class)))
+ .thenReturn(true);
+ mController.setLightSensorEnabled(true);
+ ArgumentCaptor<SensorEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(SensorEventListener.class);
+ verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
+ eq(SensorManager.SENSOR_DELAY_NORMAL), any(Handler.class));
+ SensorEventListener listener = listenerCaptor.getValue();
+
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 1));
+ mController.setLightSensorEnabled(false);
+ assertNotEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ mController.getAutomaticScreenBrightness(), 0);
+
+ mClock.fastForward(2000);
+ mController.setLightSensorEnabled(false);
+ assertEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ mController.getAutomaticScreenBrightness(), 0);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/display/TestUtils.java b/services/tests/servicestests/src/com/android/server/display/TestUtils.java
index 0454587..f3f04b8 100644
--- a/services/tests/servicestests/src/com/android/server/display/TestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/display/TestUtils.java
@@ -28,13 +28,13 @@
public final class TestUtils {
- public static SensorEvent createSensorEvent(Sensor sensor, int lux) throws Exception {
+ public static SensorEvent createSensorEvent(Sensor sensor, int value) throws Exception {
final Constructor<SensorEvent> constructor =
SensorEvent.class.getDeclaredConstructor(int.class);
constructor.setAccessible(true);
final SensorEvent event = constructor.newInstance(1);
event.sensor = sensor;
- event.values[0] = lux;
+ event.values[0] = value;
event.timestamp = SystemClock.elapsedRealtimeNanos();
return event;
}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 07009cb..7c7e2ee 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -75,6 +75,7 @@
import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
import static com.android.server.net.NetworkPolicyManagerService.UidBlockedState.getEffectiveBlockedReasons;
+import static com.android.server.net.NetworkPolicyManagerService.normalizeTemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -2059,6 +2060,18 @@
METERED_NO, actualPolicy.template.getMeteredness());
}
+ @Test
+ public void testNormalizeTemplate_duplicatedMergedImsiList() {
+ final NetworkTemplate template = new NetworkTemplate.Builder(MATCH_CARRIER)
+ .setSubscriberIds(Set.of(TEST_IMSI)).build();
+ final String[] mergedImsiGroup = new String[] {TEST_IMSI, TEST_IMSI};
+ final ArrayList<String[]> mergedList = new ArrayList<>();
+ mergedList.add(mergedImsiGroup);
+ // Verify the duplicated items in the merged IMSI list won't crash the system.
+ final NetworkTemplate result = normalizeTemplate(template, mergedList);
+ assertEquals(template, result);
+ }
+
private String formatBlockedStateError(int uid, int rule, boolean metered,
boolean backgroundRestricted) {
return String.format(
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java
index e3ca170..5bc750f 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java
@@ -258,7 +258,6 @@
.build();
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ false,
/* useProximitySensor= */ false,
/* boostScreenBrightness= */ false,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -275,7 +274,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_DIM);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(false);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(false);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(false);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
@@ -299,7 +297,6 @@
mPowerGroup.setWakeLockSummaryLocked(WAKE_LOCK_DOZE);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -316,7 +313,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_DOZE);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_ON);
@@ -339,7 +335,6 @@
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -356,7 +351,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_OFF);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
@@ -378,7 +372,6 @@
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -395,7 +388,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_OFF);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
@@ -417,7 +409,6 @@
mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -434,7 +425,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_OFF);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
@@ -455,7 +445,6 @@
.build();
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -472,7 +461,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_VR);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
@@ -494,7 +482,6 @@
mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -511,7 +498,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_OFF);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
@@ -534,7 +520,6 @@
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
mPowerGroup.setWakeLockSummaryLocked(WAKE_LOCK_SCREEN_BRIGHT);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -551,7 +536,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_BRIGHT);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
@@ -572,7 +556,6 @@
.build();
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -589,7 +572,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_BRIGHT);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
@@ -611,7 +593,6 @@
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mPowerGroup.setUserActivitySummaryLocked(USER_ACTIVITY_SCREEN_BRIGHT);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -628,7 +609,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_BRIGHT);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
@@ -649,7 +629,6 @@
.build();
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
- /* autoBrightness = */ true,
/* useProximitySensor= */ true,
/* boostScreenBrightness= */ true,
/* dozeScreenStateOverride= */ Display.STATE_ON,
@@ -666,7 +645,6 @@
mPowerGroup.mDisplayPowerRequest;
assertThat(displayPowerRequest.policy).isEqualTo(POLICY_BRIGHT);
assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
- assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 6325008..cbe8e66 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -492,6 +492,111 @@
}
@Test
+ public void testWakefulnessSleep_SoftSleepFlag_NoWakelocks() {
+ createService();
+ // Start with AWAKE state
+ startSystem();
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ // Take a nap and verify we go to sleep.
+ mService.getBinderServiceInstance().goToSleep(mClock.now(),
+ PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
+ PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ }
+
+ @Test
+ public void testWakefulnessSleep_SoftSleepFlag_WithPartialWakelock() {
+ createService();
+ // Start with AWAKE state
+ startSystem();
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ // Grab a wakelock
+ final String tag = "wakelock1";
+ final String packageName = "pkg.name";
+ final IBinder token = new Binder();
+ final int flags = PowerManager.PARTIAL_WAKE_LOCK;
+ mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+ null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+ null /* callback */);
+
+ // Take a nap and verify we stay awake.
+ mService.getBinderServiceInstance().goToSleep(mClock.now(),
+ PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
+ PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ }
+
+ @Test
+ public void testWakefulnessSleep_SoftSleepFlag_WithFullWakelock() {
+ createService();
+ // Start with AWAKE state
+ startSystem();
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ // Grab a wakelock
+ final String tag = "wakelock1";
+ final String packageName = "pkg.name";
+ final IBinder token = new Binder();
+ final int flags = PowerManager.FULL_WAKE_LOCK;
+ mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+ null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+ null /* callback */);
+
+ // Take a nap and verify we stay awake.
+ mService.getBinderServiceInstance().goToSleep(mClock.now(),
+ PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
+ PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ }
+
+ @Test
+ public void testWakefulnessSleep_SoftSleepFlag_WithScreenBrightWakelock() {
+ createService();
+ // Start with AWAKE state
+ startSystem();
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ // Grab a wakelock
+ final String tag = "wakelock1";
+ final String packageName = "pkg.name";
+ final IBinder token = new Binder();
+ final int flags = PowerManager.SCREEN_BRIGHT_WAKE_LOCK;
+ mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+ null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+ null /* callback */);
+
+ // Take a nap and verify we stay awake.
+ mService.getBinderServiceInstance().goToSleep(mClock.now(),
+ PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
+ PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ }
+ @Test
+ public void testWakefulnessSleep_SoftSleepFlag_WithScreenDimWakelock() {
+ createService();
+ // Start with AWAKE state
+ startSystem();
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ // Grab a wakelock
+ final String tag = "wakelock1";
+ final String packageName = "pkg.name";
+ final IBinder token = new Binder();
+ final int flags = PowerManager.SCREEN_DIM_WAKE_LOCK;
+ mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+ null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+ null /* callback */);
+
+ // Take a nap and verify we stay awake.
+ mService.getBinderServiceInstance().goToSleep(mClock.now(),
+ PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
+ PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ }
+
+ @Test
public void testWakefulnessAwake_AcquireCausesWakeup_turnScreenOnAllowed() {
createService();
startSystem();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 17ec19d..a017bd6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -517,7 +517,7 @@
// Mimic the behavior that display doesn't handle app's requested orientation.
final DisplayContent dc = activity.getTask().getDisplayContent();
doReturn(false).when(dc).onDescendantOrientationChanged(any());
- doReturn(false).when(dc).handlesOrientationChangeFromDescendant();
+ doReturn(false).when(dc).handlesOrientationChangeFromDescendant(anyInt());
final int requestedOrientation;
switch (newConfig.orientation) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
index b87c5a3..10540dc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
@@ -18,6 +18,8 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -471,28 +473,6 @@
}
@Test
- public void testSetIgnoreOrientationRequest() {
- final DisplayArea.Tokens area = new DisplayArea.Tokens(mWm, ABOVE_TASKS, "test");
- final WindowToken token = createWindowToken(TYPE_APPLICATION_OVERLAY);
- spyOn(token);
- doReturn(mock(DisplayContent.class)).when(token).getDisplayContent();
- doNothing().when(token).setParent(any());
- final WindowState win = createWindowState(token);
- spyOn(win);
- doNothing().when(win).setParent(any());
- win.mAttrs.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
- token.addChild(win, 0);
- area.addChild(token);
- doReturn(true).when(win).isVisible();
-
- assertEquals(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, area.getOrientation());
-
- area.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
-
- assertEquals(ActivityInfo.SCREEN_ORIENTATION_UNSET, area.getOrientation());
- }
-
- @Test
public void testSetIgnoreOrientationRequest_notCallSuperOnDescendantOrientationChanged() {
final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
final Task stack =
@@ -514,7 +494,49 @@
}
@Test
- public void testSetIgnoreOrientationRequest_updateOrientationRequestingTaskDisplayArea() {
+ public void testSetIgnoreOrientationRequest_callSuperOnDescendantOrientationChangedNoSensor() {
+ final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
+ final Task stack =
+ new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
+ final ActivityRecord activity = stack.getTopNonFinishingActivity();
+
+ tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
+
+ verify(tda).onDescendantOrientationChanged(any());
+ verify(mDisplayContent).onDescendantOrientationChanged(any());
+
+ tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
+
+ verify(tda).onDescendantOrientationChanged(any());
+ verify(mDisplayContent).onDescendantOrientationChanged(any());
+ }
+
+ @Test
+ public void testSetIgnoreOrientationRequest_callSuperOnDescendantOrientationChangedLocked() {
+ final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
+ final Task stack =
+ new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
+ final ActivityRecord activity = stack.getTopNonFinishingActivity();
+
+ tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_LOCKED);
+
+ verify(tda).onDescendantOrientationChanged(any());
+ verify(mDisplayContent).onDescendantOrientationChanged(any());
+
+ tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_LOCKED);
+
+ verify(tda).onDescendantOrientationChanged(any());
+ verify(mDisplayContent).onDescendantOrientationChanged(any());
+ }
+
+ @Test
+ public void testGetOrientationRequestingTaskDisplayArea_updateOrientationTaskDisplayArea() {
final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
final Task stack =
new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
@@ -526,7 +548,7 @@
// TDA is no longer handling orientation request, clear the last focused TDA.
tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isNull();
+ assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isEqualTo(tda);
// TDA now handles orientation request, update last focused TDA based on the focused app.
tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
index 3ab4495..232b9b2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -17,6 +17,8 @@
package com.android.server.wm;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
@@ -163,6 +165,30 @@
}
@Test
+ public void testIgnoreOrientationRequest_displayReceiveOrientationChangeForNoSensor() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
+
+ verify(mFirstRoot).onDescendantOrientationChanged(any());
+ verify(mDisplay).onDescendantOrientationChanged(any());
+ }
+
+ @Test
+ public void testIgnoreOrientationRequest_displayReceiveOrientationChangeForLocked() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LOCKED);
+
+ verify(mFirstRoot).onDescendantOrientationChanged(any());
+ verify(mDisplay).onDescendantOrientationChanged(any());
+ }
+
+ @Test
public void testLaunchPortraitApp_fillsDisplayAreaGroup() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -215,6 +241,21 @@
}
@Test
+ public void testLaunchNoSensorApp_noSizeCompatAfterRotation() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+
+ rotateDisplay(mDisplay, ROTATION_90);
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+ }
+
+ @Test
public void testLaunchLandscapeApp_activityIsLetterboxForFixedOrientationInDisplayAreaGroup() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -236,6 +277,26 @@
}
@Test
+ public void testLaunchNoSensorApp_activityIsNotLetterboxForFixedOrientationDisplayAreaGroup() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ }
+
+ @Test
+ public void testLaunchLockedApp_activityIsNotLetterboxForFixedOrientationInDisplayAreaGroup() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LOCKED);
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ }
+
+ @Test
public void testLaunchLandscapeApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -265,6 +326,20 @@
}
@Test
+ public void testLaunchNoSensorApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
+
+ rotateDisplay(mDisplay, ROTATION_90);
+
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+ }
+
+ @Test
public void testPlaceImeContainer_reparentToTargetDisplayAreaGroup() {
setupImeWindow();
final DisplayArea.Tokens imeContainer = mDisplay.getImeContainer();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index e660db5..582ddf2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -29,8 +29,9 @@
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -422,24 +423,26 @@
// Activity on TDA1 is focused
mDisplayContent.setFocusedApp(firstActivity);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isTrue();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
+ final int testOrientation = SCREEN_ORIENTATION_PORTRAIT;
+
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
// No focused app, TDA1 is still recorded as last focused.
mDisplayContent.setFocusedApp(null);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isTrue();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
// Activity on TDA2 is focused
mDisplayContent.setFocusedApp(secondActivity);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isTrue();
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
}
@Test
- public void testIsLastFocused_onlyCountIfTaskDisplayAreaHandlesOrientationRequest() {
+ public void testCanSpecifyOrientation() {
final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
@@ -455,34 +458,88 @@
firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
- // Activity on TDA1 is focused, but TDA1 doesn't respect orientation request
+ final int testOrientation = SCREEN_ORIENTATION_PORTRAIT;
+
+ // Activity on TDA1 is focused, but TDA1 cannot specify orientation because
+ // ignoreOrientationRequest is true
+ // Activity on TDA2 has ignoreOrientationRequest false but it doesn't have focus so it
+ // cannot specify orientation
mDisplayContent.setFocusedApp(firstActivity);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
- // Activity on TDA2 is focused, and TDA2 respects orientation request
+ // Activity on TDA1 is not focused, and so it cannot specify orientation
+ // Activity on TDA2 is focused, and it can specify orientation because
+ // ignoreOrientationRequest is false
mDisplayContent.setFocusedApp(secondActivity);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isTrue();
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
}
@Test
- public void testIgnoreOrientationRequest() {
- final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
- final Task task = taskDisplayArea.createRootTask(
+ public void testCanSpecifyOrientationNoSensor() {
+ final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+ final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+ mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
+ FEATURE_VENDOR_FIRST);
+ final Task firstRootTask = firstTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
- final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
+ final Task secondRootTask = secondTaskDisplayArea.createRootTask(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+ .setTask(firstRootTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+ .setTask(secondRootTask).build();
+ firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
- mDisplayContent.setFocusedApp(activity);
- activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+ final int testOrientation = SCREEN_ORIENTATION_NOSENSOR;
- assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
+ // ignoreOrientationRequest is always false for SCREEN_ORIENTATION_NOSENSOR so
+ // only the TDAs with focus can specify orientations
+ mDisplayContent.setFocusedApp(firstActivity);
- taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
- assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET);
+ mDisplayContent.setFocusedApp(secondActivity);
+
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ }
+
+ @Test
+ public void testCanSpecifyOrientationLocked() {
+ final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+ final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+ mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
+ FEATURE_VENDOR_FIRST);
+ final Task firstRootTask = firstTaskDisplayArea.createRootTask(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final Task secondRootTask = secondTaskDisplayArea.createRootTask(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+ .setTask(firstRootTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+ .setTask(secondRootTask).build();
+ firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+
+ final int testOrientation = SCREEN_ORIENTATION_LOCKED;
+
+ // ignoreOrientationRequest is always false for SCREEN_ORIENTATION_NOSENSOR so
+ // only the TDAs with focus can specify orientations
+ mDisplayContent.setFocusedApp(firstActivity);
+
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+
+ mDisplayContent.setFocusedApp(secondActivity);
+
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index db65f49..140051d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -247,6 +247,7 @@
mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents();
+ assertTrue(mTaskFragment.mTaskFragmentVanishedSent);
assertTaskFragmentVanishedTransaction();
}
@@ -259,10 +260,12 @@
mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents();
+ assertTrue(mTaskFragment.mTaskFragmentVanishedSent);
assertTaskFragmentVanishedTransaction();
// Not trigger onTaskFragmentInfoChanged.
// Call onTaskFragmentAppeared before calling onTaskFragmentInfoChanged.
+ mTaskFragment.mTaskFragmentVanishedSent = false;
mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents();
clearInvocations(mOrganizer);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 11ac929..c893255 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -38,6 +38,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -98,12 +99,25 @@
}
@Test
- public void testOnConfigurationChanged_updateSurface() {
- final Rect bounds = new Rect(100, 100, 1100, 1100);
+ public void testOnConfigurationChanged() {
+ final Configuration parentConfig = mTaskFragment.getParent().getConfiguration();
+ final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
+ parentConfig.smallestScreenWidthDp += 10;
+ final int parentSw = parentConfig.smallestScreenWidthDp;
+ final Rect bounds = new Rect(parentBounds);
+ bounds.inset(100, 100);
mTaskFragment.setBounds(bounds);
+ mTaskFragment.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ // Calculate its own sw with smaller bounds in multi-window mode.
+ assertNotEquals(parentSw, mTaskFragment.getConfiguration().smallestScreenWidthDp);
- verify(mTransaction).setPosition(mLeash, 100, 100);
- verify(mTransaction).setWindowCrop(mLeash, 1000, 1000);
+ verify(mTransaction).setPosition(mLeash, bounds.left, bounds.top);
+ verify(mTransaction).setWindowCrop(mLeash, bounds.width(), bounds.height());
+
+ mTaskFragment.setBounds(parentBounds);
+ mTaskFragment.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ // Inherit parent's sw in fullscreen mode.
+ assertEquals(parentSw, mTaskFragment.getConfiguration().smallestScreenWidthDp);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 0c8e89a8..eac6777 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -57,6 +57,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
@@ -392,12 +393,16 @@
leafTask1.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_HOME);
leafTask2.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_STANDARD);
+ // We need to use an orientation that is not an exception for the
+ // ignoreOrientationRequest flag.
+ final int orientation = SCREEN_ORIENTATION_PORTRAIT;
+
assertEquals(leafTask2, rootTask.getTopChild());
- assertTrue(rootTask.handlesOrientationChangeFromDescendant());
+ assertTrue(rootTask.handlesOrientationChangeFromDescendant(orientation));
// Treat orientation request from home as handled.
- assertTrue(leafTask1.handlesOrientationChangeFromDescendant());
+ assertTrue(leafTask1.handlesOrientationChangeFromDescendant(orientation));
// Orientation request from standard activity in multi window will not be handled.
- assertFalse(leafTask2.handlesOrientationChangeFromDescendant());
+ assertFalse(leafTask2.handlesOrientationChangeFromDescendant(orientation));
}
@Test
@@ -636,7 +641,8 @@
doReturn(parentWindowContainer).when(task).getParent();
doReturn(display.getDefaultTaskDisplayArea()).when(task).getDisplayArea();
doReturn(rootTask).when(task).getRootTask();
- doReturn(true).when(parentWindowContainer).handlesOrientationChangeFromDescendant();
+ doReturn(true).when(parentWindowContainer)
+ .handlesOrientationChangeFromDescendant(anyInt());
// Setting app to fixed portrait fits within parent, but Task shouldn't adjust the
// bounds because its parent says it will handle it at a later time.
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index ef3ddb7..ed7d123 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -662,13 +662,13 @@
public void testSetOrientation() {
final TestWindowContainer root = spy(new TestWindowContainerBuilder(mWm).build());
final TestWindowContainer child = spy(root.addChildWindow());
- doReturn(true).when(root).handlesOrientationChangeFromDescendant();
+ doReturn(true).when(root).handlesOrientationChangeFromDescendant(anyInt());
child.getWindowConfiguration().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
child.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
// The ancestor should decide whether to dispatch the configuration change.
verify(child, never()).onConfigurationChanged(any());
- doReturn(false).when(root).handlesOrientationChangeFromDescendant();
+ doReturn(false).when(root).handlesOrientationChangeFromDescendant(anyInt());
child.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
// The ancestor doesn't handle the request so the descendant applies the change directly.
verify(child).onConfigurationChanged(any());
@@ -843,11 +843,14 @@
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = spy(builder.build());
- final TestWindowContainer child = root.addChildWindow();
- assertFalse(child.handlesOrientationChangeFromDescendant());
+ // We use an orientation that is not an exception for the ignoreOrientationRequest flag
+ final int orientation = SCREEN_ORIENTATION_PORTRAIT;
- Mockito.doReturn(true).when(root).handlesOrientationChangeFromDescendant();
- assertTrue(child.handlesOrientationChangeFromDescendant());
+ final TestWindowContainer child = root.addChildWindow();
+ assertFalse(child.handlesOrientationChangeFromDescendant(orientation));
+
+ Mockito.doReturn(true).when(root).handlesOrientationChangeFromDescendant(anyInt());
+ assertTrue(child.handlesOrientationChangeFromDescendant(orientation));
}
@Test
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java
new file mode 100644
index 0000000..6c8feb7
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.voiceinteraction;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.service.voice.HotwordAudioStream.KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES;
+
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__CLOSE_ERROR_FROM_SYSTEM;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__EMPTY_AUDIO_STREAM_LIST;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__ENDED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__ILLEGAL_COPY_BUFFER_SIZE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__INTERRUPTED_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__NO_PERMISSION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__STARTED;
+import static com.android.server.voiceinteraction.HotwordDetectionConnection.DEBUG;
+
+import android.annotation.NonNull;
+import android.app.AppOpsManager;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.service.voice.HotwordAudioStream;
+import android.service.voice.HotwordDetectedResult;
+import android.util.Slog;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Copies the audio streams in {@link HotwordDetectedResult}s. This allows the system to manage the
+ * lifetime of the {@link ParcelFileDescriptor}s and ensures that the flow of data is in the right
+ * direction from the {@link android.service.voice.HotwordDetectionService} to the client (i.e., the
+ * voice interactor).
+ *
+ * @hide
+ */
+final class HotwordAudioStreamCopier {
+
+ private static final String TAG = "HotwordAudioStreamCopier";
+ private static final String OP_MESSAGE = "Streaming hotword audio to VoiceInteractionService";
+ private static final String TASK_ID_PREFIX = "HotwordDetectedResult@";
+ private static final String THREAD_NAME_PREFIX = "Copy-";
+
+ // Corresponds to the OS pipe capacity in bytes
+ private static final int MAX_COPY_BUFFER_LENGTH_BYTES = 65_536;
+ private static final int DEFAULT_COPY_BUFFER_LENGTH_BYTES = 32_768;
+
+ private final AppOpsManager mAppOpsManager;
+ private final int mDetectorType;
+ private final int mVoiceInteractorUid;
+ private final String mVoiceInteractorPackageName;
+ private final String mVoiceInteractorAttributionTag;
+ private final ExecutorService mExecutorService = Executors.newCachedThreadPool();
+
+ HotwordAudioStreamCopier(@NonNull AppOpsManager appOpsManager, int detectorType,
+ int voiceInteractorUid, @NonNull String voiceInteractorPackageName,
+ @NonNull String voiceInteractorAttributionTag) {
+ mAppOpsManager = appOpsManager;
+ mDetectorType = detectorType;
+ mVoiceInteractorUid = voiceInteractorUid;
+ mVoiceInteractorPackageName = voiceInteractorPackageName;
+ mVoiceInteractorAttributionTag = voiceInteractorAttributionTag;
+ }
+
+ /**
+ * Starts copying the audio streams in the given {@link HotwordDetectedResult}.
+ * <p>
+ * The returned {@link HotwordDetectedResult} is identical the one that was passed in, except
+ * that the {@link ParcelFileDescriptor}s within {@link HotwordDetectedResult#getAudioStreams()}
+ * are replaced with descriptors from pipes managed by {@link HotwordAudioStreamCopier}. The
+ * returned value should be passed on to the client (i.e., the voice interactor).
+ * </p>
+ *
+ * @throws IOException If there was an error creating the managed pipe.
+ */
+ @NonNull
+ public HotwordDetectedResult startCopyingAudioStreams(@NonNull HotwordDetectedResult result)
+ throws IOException {
+ List<HotwordAudioStream> audioStreams = result.getAudioStreams();
+ if (audioStreams.isEmpty()) {
+ HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__EMPTY_AUDIO_STREAM_LIST,
+ mVoiceInteractorUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+ /* streamCount= */ 0);
+ return result;
+ }
+
+ final int audioStreamCount = audioStreams.size();
+ List<HotwordAudioStream> newAudioStreams = new ArrayList<>(audioStreams.size());
+ List<CopyTaskInfo> copyTaskInfos = new ArrayList<>(audioStreams.size());
+ int totalMetadataBundleSizeBytes = 0;
+ int totalInitialAudioSizeBytes = 0;
+ for (HotwordAudioStream audioStream : audioStreams) {
+ ParcelFileDescriptor[] clientPipe = ParcelFileDescriptor.createReliablePipe();
+ ParcelFileDescriptor clientAudioSource = clientPipe[0];
+ ParcelFileDescriptor clientAudioSink = clientPipe[1];
+ HotwordAudioStream newAudioStream =
+ audioStream.buildUpon().setAudioStreamParcelFileDescriptor(
+ clientAudioSource).build();
+ newAudioStreams.add(newAudioStream);
+
+ int copyBufferLength = DEFAULT_COPY_BUFFER_LENGTH_BYTES;
+ PersistableBundle metadata = audioStream.getMetadata();
+ totalMetadataBundleSizeBytes += HotwordDetectedResult.getParcelableSize(metadata);
+ if (metadata.containsKey(KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES)) {
+ copyBufferLength = metadata.getInt(KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES, -1);
+ if (copyBufferLength < 1 || copyBufferLength > MAX_COPY_BUFFER_LENGTH_BYTES) {
+ HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__ILLEGAL_COPY_BUFFER_SIZE,
+ mVoiceInteractorUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+ audioStreamCount);
+ Slog.w(TAG, "Attempted to set an invalid copy buffer length ("
+ + copyBufferLength + ") for: " + audioStream);
+ copyBufferLength = DEFAULT_COPY_BUFFER_LENGTH_BYTES;
+ } else if (DEBUG) {
+ Slog.i(TAG, "Copy buffer length set to " + copyBufferLength + " for: "
+ + audioStream);
+ }
+ }
+
+ // We are including the non-streamed initial audio
+ // (HotwordAudioStream.getInitialAudio()) bytes in the "stream" size metrics.
+ totalInitialAudioSizeBytes += audioStream.getInitialAudio().length;
+
+ ParcelFileDescriptor serviceAudioSource =
+ audioStream.getAudioStreamParcelFileDescriptor();
+ copyTaskInfos.add(new CopyTaskInfo(serviceAudioSource, clientAudioSink,
+ copyBufferLength));
+ }
+
+ String resultTaskId = TASK_ID_PREFIX + System.identityHashCode(result);
+ mExecutorService.execute(
+ new HotwordDetectedResultCopyTask(resultTaskId, copyTaskInfos,
+ totalMetadataBundleSizeBytes, totalInitialAudioSizeBytes));
+
+ return result.buildUpon().setAudioStreams(newAudioStreams).build();
+ }
+
+ private static class CopyTaskInfo {
+ private final ParcelFileDescriptor mSource;
+ private final ParcelFileDescriptor mSink;
+ private final int mCopyBufferLength;
+
+ CopyTaskInfo(ParcelFileDescriptor source, ParcelFileDescriptor sink, int copyBufferLength) {
+ mSource = source;
+ mSink = sink;
+ mCopyBufferLength = copyBufferLength;
+ }
+ }
+
+ private class HotwordDetectedResultCopyTask implements Runnable {
+ private final String mResultTaskId;
+ private final List<CopyTaskInfo> mCopyTaskInfos;
+ private final int mTotalMetadataSizeBytes;
+ private final int mTotalInitialAudioSizeBytes;
+ private final ExecutorService mExecutorService = Executors.newCachedThreadPool();
+
+ HotwordDetectedResultCopyTask(String resultTaskId, List<CopyTaskInfo> copyTaskInfos,
+ int totalMetadataSizeBytes, int totalInitialAudioSizeBytes) {
+ mResultTaskId = resultTaskId;
+ mCopyTaskInfos = copyTaskInfos;
+ mTotalMetadataSizeBytes = totalMetadataSizeBytes;
+ mTotalInitialAudioSizeBytes = totalInitialAudioSizeBytes;
+ }
+
+ @Override
+ public void run() {
+ Thread.currentThread().setName(THREAD_NAME_PREFIX + mResultTaskId);
+ int size = mCopyTaskInfos.size();
+ List<SingleAudioStreamCopyTask> tasks = new ArrayList<>(size);
+ for (int i = 0; i < size; i++) {
+ CopyTaskInfo copyTaskInfo = mCopyTaskInfos.get(i);
+ String streamTaskId = mResultTaskId + "@" + i;
+ tasks.add(new SingleAudioStreamCopyTask(streamTaskId, copyTaskInfo.mSource,
+ copyTaskInfo.mSink, copyTaskInfo.mCopyBufferLength, mDetectorType,
+ mVoiceInteractorUid));
+ }
+
+ if (mAppOpsManager.startOpNoThrow(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD,
+ mVoiceInteractorUid, mVoiceInteractorPackageName,
+ mVoiceInteractorAttributionTag, OP_MESSAGE) == MODE_ALLOWED) {
+ try {
+ HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__STARTED,
+ mVoiceInteractorUid, mTotalInitialAudioSizeBytes,
+ mTotalMetadataSizeBytes, size);
+ // TODO(b/244599891): Set timeout, close after inactivity
+ mExecutorService.invokeAll(tasks);
+
+ // We are including the non-streamed initial audio
+ // (HotwordAudioStream.getInitialAudio()) bytes in the "stream" size metrics.
+ int totalStreamSizeBytes = mTotalInitialAudioSizeBytes;
+ for (SingleAudioStreamCopyTask task : tasks) {
+ totalStreamSizeBytes += task.mTotalCopiedBytes;
+ }
+
+ Slog.i(TAG, mResultTaskId + ": Task was completed. Total bytes egressed: "
+ + totalStreamSizeBytes + " (including " + mTotalInitialAudioSizeBytes
+ + " bytes NOT streamed), total metadata bundle size bytes: "
+ + mTotalMetadataSizeBytes);
+ HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__ENDED,
+ mVoiceInteractorUid, totalStreamSizeBytes, mTotalMetadataSizeBytes,
+ size);
+ } catch (InterruptedException e) {
+ // We are including the non-streamed initial audio
+ // (HotwordAudioStream.getInitialAudio()) bytes in the "stream" size metrics.
+ int totalStreamSizeBytes = mTotalInitialAudioSizeBytes;
+ for (SingleAudioStreamCopyTask task : tasks) {
+ totalStreamSizeBytes += task.mTotalCopiedBytes;
+ }
+
+ HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__INTERRUPTED_EXCEPTION,
+ mVoiceInteractorUid, totalStreamSizeBytes, mTotalMetadataSizeBytes,
+ size);
+ Slog.i(TAG, mResultTaskId + ": Task was interrupted. Total bytes egressed: "
+ + totalStreamSizeBytes + " (including " + mTotalInitialAudioSizeBytes
+ + " bytes NOT streamed), total metadata bundle size bytes: "
+ + mTotalMetadataSizeBytes);
+ bestEffortPropagateError(e.getMessage());
+ } finally {
+ mAppOpsManager.finishOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD,
+ mVoiceInteractorUid, mVoiceInteractorPackageName,
+ mVoiceInteractorAttributionTag);
+ }
+ } else {
+ HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__NO_PERMISSION,
+ mVoiceInteractorUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+ size);
+ bestEffortPropagateError(
+ "Failed to obtain RECORD_AUDIO_HOTWORD permission for voice interactor with"
+ + " uid=" + mVoiceInteractorUid
+ + " packageName=" + mVoiceInteractorPackageName
+ + " attributionTag=" + mVoiceInteractorAttributionTag);
+ }
+ }
+
+ private void bestEffortPropagateError(@NonNull String errorMessage) {
+ try {
+ for (CopyTaskInfo copyTaskInfo : mCopyTaskInfos) {
+ copyTaskInfo.mSource.closeWithError(errorMessage);
+ copyTaskInfo.mSink.closeWithError(errorMessage);
+ }
+ HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__CLOSE_ERROR_FROM_SYSTEM,
+ mVoiceInteractorUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+ mCopyTaskInfos.size());
+ } catch (IOException e) {
+ Slog.e(TAG, mResultTaskId + ": Failed to propagate error", e);
+ }
+ }
+ }
+
+ private static class SingleAudioStreamCopyTask implements Callable<Void> {
+ private final String mStreamTaskId;
+ private final ParcelFileDescriptor mAudioSource;
+ private final ParcelFileDescriptor mAudioSink;
+ private final int mCopyBufferLength;
+ private final int mDetectorType;
+ private final int mUid;
+
+ private volatile int mTotalCopiedBytes = 0;
+
+ SingleAudioStreamCopyTask(String streamTaskId, ParcelFileDescriptor audioSource,
+ ParcelFileDescriptor audioSink, int copyBufferLength, int detectorType, int uid) {
+ mStreamTaskId = streamTaskId;
+ mAudioSource = audioSource;
+ mAudioSink = audioSink;
+ mCopyBufferLength = copyBufferLength;
+ mDetectorType = detectorType;
+ mUid = uid;
+ }
+
+ @Override
+ public Void call() throws Exception {
+ Thread.currentThread().setName(THREAD_NAME_PREFIX + mStreamTaskId);
+
+ // Note: We are intentionally NOT using try-with-resources here. If we did,
+ // the ParcelFileDescriptors will be automatically closed WITHOUT errors before we go
+ // into the IOException-catch block. We want to propagate the error while closing the
+ // PFDs.
+ InputStream fis = null;
+ OutputStream fos = null;
+ try {
+ fis = new ParcelFileDescriptor.AutoCloseInputStream(mAudioSource);
+ fos = new ParcelFileDescriptor.AutoCloseOutputStream(mAudioSink);
+ byte[] buffer = new byte[mCopyBufferLength];
+ while (true) {
+ if (Thread.interrupted()) {
+ Slog.e(TAG,
+ mStreamTaskId + ": SingleAudioStreamCopyTask task was interrupted");
+ break;
+ }
+
+ int bytesRead = fis.read(buffer);
+ if (bytesRead < 0) {
+ Slog.i(TAG, mStreamTaskId + ": Reached end of audio stream");
+ break;
+ }
+ if (bytesRead > 0) {
+ if (DEBUG) {
+ // TODO(b/244599440): Add proper logging
+ Slog.d(TAG, mStreamTaskId + ": Copied " + bytesRead
+ + " bytes from audio stream. First 20 bytes=" + Arrays.toString(
+ Arrays.copyOfRange(buffer, 0, 20)));
+ }
+ fos.write(buffer, 0, bytesRead);
+ mTotalCopiedBytes += bytesRead;
+ }
+ // TODO(b/244599891): Close PFDs after inactivity
+ }
+ } catch (IOException e) {
+ mAudioSource.closeWithError(e.getMessage());
+ mAudioSink.closeWithError(e.getMessage());
+ Slog.e(TAG, mStreamTaskId + ": Failed to copy audio stream", e);
+ HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__CLOSE_ERROR_FROM_SYSTEM,
+ mUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+ /* streamCount= */ 0);
+ } finally {
+ if (fis != null) {
+ fis.close();
+ }
+ if (fos != null) {
+ fos.close();
+ }
+ }
+
+ return null;
+ }
+ }
+
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamManager.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamManager.java
deleted file mode 100644
index d5eea1f..0000000
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamManager.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.voiceinteraction;
-
-import static android.app.AppOpsManager.MODE_ALLOWED;
-
-import static com.android.server.voiceinteraction.HotwordDetectionConnection.DEBUG;
-
-import android.annotation.NonNull;
-import android.app.AppOpsManager;
-import android.media.permission.Identity;
-import android.os.ParcelFileDescriptor;
-import android.service.voice.HotwordAudioStream;
-import android.service.voice.HotwordDetectedResult;
-import android.util.Pair;
-import android.util.Slog;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-final class HotwordAudioStreamManager {
-
- private static final String TAG = "HotwordAudioStreamManager";
- private static final String OP_MESSAGE = "Streaming hotword audio to VoiceInteractionService";
- private static final String TASK_ID_PREFIX = "HotwordDetectedResult@";
- private static final String THREAD_NAME_PREFIX = "Copy-";
-
- private final AppOpsManager mAppOpsManager;
- private final Identity mVoiceInteractorIdentity;
- private final ExecutorService mExecutorService = Executors.newCachedThreadPool();
-
- HotwordAudioStreamManager(@NonNull AppOpsManager appOpsManager,
- @NonNull Identity voiceInteractorIdentity) {
- mAppOpsManager = appOpsManager;
- mVoiceInteractorIdentity = voiceInteractorIdentity;
- }
-
- /**
- * Starts copying the audio streams in the given {@link HotwordDetectedResult}.
- * <p>
- * The returned {@link HotwordDetectedResult} is identical the one that was passed in, except
- * that the {@link ParcelFileDescriptor}s within {@link HotwordDetectedResult#getAudioStreams()}
- * are replaced with descriptors from pipes managed by {@link HotwordAudioStreamManager}. The
- * returned value should be passed on to the client (i.e., the voice interactor).
- * </p>
- *
- * @throws IOException If there was an error creating the managed pipe.
- */
- @NonNull
- public HotwordDetectedResult startCopyingAudioStreams(@NonNull HotwordDetectedResult result)
- throws IOException {
- List<HotwordAudioStream> audioStreams = result.getAudioStreams();
- if (audioStreams.isEmpty()) {
- return result;
- }
-
- List<HotwordAudioStream> newAudioStreams = new ArrayList<>(audioStreams.size());
- List<Pair<ParcelFileDescriptor, ParcelFileDescriptor>> sourcesAndSinks = new ArrayList<>(
- audioStreams.size());
- for (HotwordAudioStream audioStream : audioStreams) {
- ParcelFileDescriptor[] clientPipe = ParcelFileDescriptor.createReliablePipe();
- ParcelFileDescriptor clientAudioSource = clientPipe[0];
- ParcelFileDescriptor clientAudioSink = clientPipe[1];
- HotwordAudioStream newAudioStream =
- audioStream.buildUpon().setAudioStreamParcelFileDescriptor(
- clientAudioSource).build();
- newAudioStreams.add(newAudioStream);
-
- ParcelFileDescriptor serviceAudioSource =
- audioStream.getAudioStreamParcelFileDescriptor();
- sourcesAndSinks.add(new Pair<>(serviceAudioSource, clientAudioSink));
- }
-
- String resultTaskId = TASK_ID_PREFIX + System.identityHashCode(result);
- mExecutorService.execute(new HotwordDetectedResultCopyTask(resultTaskId, sourcesAndSinks));
-
- return result.buildUpon().setAudioStreams(newAudioStreams).build();
- }
-
- private class HotwordDetectedResultCopyTask implements Runnable {
- private final String mResultTaskId;
- private final List<Pair<ParcelFileDescriptor, ParcelFileDescriptor>> mSourcesAndSinks;
- private final ExecutorService mExecutorService = Executors.newCachedThreadPool();
-
- HotwordDetectedResultCopyTask(String resultTaskId,
- List<Pair<ParcelFileDescriptor, ParcelFileDescriptor>> sourcesAndSinks) {
- mResultTaskId = resultTaskId;
- mSourcesAndSinks = sourcesAndSinks;
- }
-
- @Override
- public void run() {
- Thread.currentThread().setName(THREAD_NAME_PREFIX + mResultTaskId);
- int size = mSourcesAndSinks.size();
- List<SingleAudioStreamCopyTask> tasks = new ArrayList<>(size);
- for (int i = 0; i < size; i++) {
- Pair<ParcelFileDescriptor, ParcelFileDescriptor> sourceAndSink =
- mSourcesAndSinks.get(i);
- ParcelFileDescriptor serviceAudioSource = sourceAndSink.first;
- ParcelFileDescriptor clientAudioSink = sourceAndSink.second;
- String streamTaskId = mResultTaskId + "@" + i;
- tasks.add(new SingleAudioStreamCopyTask(streamTaskId, serviceAudioSource,
- clientAudioSink));
- }
-
- if (mAppOpsManager.startOpNoThrow(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD,
- mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
- mVoiceInteractorIdentity.attributionTag, OP_MESSAGE) == MODE_ALLOWED) {
- try {
- // TODO(b/244599891): Set timeout, close after inactivity
- mExecutorService.invokeAll(tasks);
- } catch (InterruptedException e) {
- Slog.e(TAG, mResultTaskId + ": Task was interrupted", e);
- bestEffortPropagateError(e.getMessage());
- } finally {
- mAppOpsManager.finishOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD,
- mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
- mVoiceInteractorIdentity.attributionTag);
- }
- } else {
- bestEffortPropagateError(
- "Failed to obtain RECORD_AUDIO_HOTWORD permission for "
- + SoundTriggerSessionPermissionsDecorator.toString(
- mVoiceInteractorIdentity));
- }
- }
-
- private void bestEffortPropagateError(@NonNull String errorMessage) {
- try {
- for (Pair<ParcelFileDescriptor, ParcelFileDescriptor> sourceAndSink :
- mSourcesAndSinks) {
- ParcelFileDescriptor serviceAudioSource = sourceAndSink.first;
- ParcelFileDescriptor clientAudioSink = sourceAndSink.second;
- serviceAudioSource.closeWithError(errorMessage);
- clientAudioSink.closeWithError(errorMessage);
- }
- } catch (IOException e) {
- Slog.e(TAG, mResultTaskId + ": Failed to propagate error", e);
- }
- }
- }
-
- private static class SingleAudioStreamCopyTask implements Callable<Void> {
- // TODO: Make this buffer size customizable from updateState()
- private static final int COPY_BUFFER_LENGTH = 2_560;
-
- private final String mStreamTaskId;
- private final ParcelFileDescriptor mAudioSource;
- private final ParcelFileDescriptor mAudioSink;
-
- SingleAudioStreamCopyTask(String streamTaskId, ParcelFileDescriptor audioSource,
- ParcelFileDescriptor audioSink) {
- mStreamTaskId = streamTaskId;
- mAudioSource = audioSource;
- mAudioSink = audioSink;
- }
-
- @Override
- public Void call() throws Exception {
- Thread.currentThread().setName(THREAD_NAME_PREFIX + mStreamTaskId);
-
- // Note: We are intentionally NOT using try-with-resources here. If we did,
- // the ParcelFileDescriptors will be automatically closed WITHOUT errors before we go
- // into the IOException-catch block. We want to propagate the error while closing the
- // PFDs.
- InputStream fis = null;
- OutputStream fos = null;
- try {
- fis = new ParcelFileDescriptor.AutoCloseInputStream(mAudioSource);
- fos = new ParcelFileDescriptor.AutoCloseOutputStream(mAudioSink);
- byte[] buffer = new byte[COPY_BUFFER_LENGTH];
- while (true) {
- if (Thread.interrupted()) {
- Slog.e(TAG,
- mStreamTaskId + ": SingleAudioStreamCopyTask task was interrupted");
- break;
- }
-
- int bytesRead = fis.read(buffer);
- if (bytesRead < 0) {
- Slog.i(TAG, mStreamTaskId + ": Reached end of audio stream");
- break;
- }
- if (bytesRead > 0) {
- if (DEBUG) {
- // TODO(b/244599440): Add proper logging
- Slog.d(TAG, mStreamTaskId + ": Copied " + bytesRead
- + " bytes from audio stream. First 20 bytes=" + Arrays.toString(
- Arrays.copyOfRange(buffer, 0, 20)));
- }
- fos.write(buffer, 0, bytesRead);
- }
- // TODO(b/244599891): Close PFDs after inactivity
- }
- } catch (IOException e) {
- mAudioSource.closeWithError(e.getMessage());
- mAudioSink.closeWithError(e.getMessage());
- Slog.e(TAG, mStreamTaskId + ": Failed to copy audio stream", e);
- } finally {
- if (fis != null) {
- fis.close();
- }
- if (fos != null) {
- fos.close();
- }
- }
-
- return null;
- }
- }
-
-}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 6f7d80c..55bf2ab 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -170,7 +170,7 @@
private final ScheduledExecutorService mScheduledExecutorService =
Executors.newSingleThreadScheduledExecutor();
private final AppOpsManager mAppOpsManager;
- private final HotwordAudioStreamManager mHotwordAudioStreamManager;
+ private final HotwordAudioStreamCopier mHotwordAudioStreamCopier;
@Nullable private final ScheduledFuture<?> mCancellationTaskFuture;
private final AtomicBoolean mUpdateStateAfterStartFinished = new AtomicBoolean(false);
private final IBinder.DeathRecipient mAudioServerDeathRecipient = this::audioServerDied;
@@ -232,8 +232,9 @@
mVoiceInteractionServiceUid = voiceInteractionServiceUid;
mVoiceInteractorIdentity = voiceInteractorIdentity;
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
- mHotwordAudioStreamManager = new HotwordAudioStreamManager(mAppOpsManager,
- mVoiceInteractorIdentity);
+ mHotwordAudioStreamCopier = new HotwordAudioStreamCopier(mAppOpsManager, detectorType,
+ mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
+ mVoiceInteractorIdentity.attributionTag);
mDetectionComponentName = serviceName;
mUser = userId;
mCallback = callback;
@@ -267,7 +268,8 @@
synchronized (mLock) {
restartProcessLocked();
HotwordMetricsLogger.writeServiceRestartEvent(mDetectorType,
- HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__SCHEDULE);
+ HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__SCHEDULE,
+ mVoiceInteractionServiceUid);
}
}, mReStartPeriodSeconds, mReStartPeriodSeconds, TimeUnit.SECONDS);
}
@@ -302,7 +304,8 @@
// conditions with audio reading in the service.
restartProcessLocked();
HotwordMetricsLogger.writeServiceRestartEvent(mDetectorType,
- HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__AUDIO_SERVICE_DIED);
+ HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__AUDIO_SERVICE_DIED,
+ mVoiceInteractionServiceUid);
}
}
@@ -333,13 +336,14 @@
try {
mCallback.onStatusReported(status);
HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
- initResultMetricsResult);
+ initResultMetricsResult, mVoiceInteractionServiceUid);
} catch (RemoteException e) {
// TODO: Add a new atom for RemoteException case, the error doesn't very
// correct here
Slog.w(TAG, "Failed to report initialization status: " + e);
HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
- METRICS_INIT_CALLBACK_STATE_ERROR);
+ METRICS_INIT_CALLBACK_STATE_ERROR,
+ mVoiceInteractionServiceUid);
}
}
};
@@ -362,11 +366,12 @@
try {
mCallback.onStatusReported(INITIALIZATION_STATUS_UNKNOWN);
HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
- METRICS_INIT_UNKNOWN_TIMEOUT);
+ METRICS_INIT_UNKNOWN_TIMEOUT, mVoiceInteractionServiceUid);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to report initialization status UNKNOWN", e);
HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
- METRICS_INIT_CALLBACK_STATE_ERROR);
+ METRICS_INIT_CALLBACK_STATE_ERROR,
+ mVoiceInteractionServiceUid);
}
} else if (err != null) {
Slog.w(TAG, "Failed to update state: " + err);
@@ -469,12 +474,14 @@
synchronized (mLock) {
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED);
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED,
+ mVoiceInteractionServiceUid);
if (!mPerformingSoftwareHotwordDetection) {
Slog.i(TAG, "Hotword detection has already completed");
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- METRICS_KEYPHRASE_TRIGGERED_DETECT_UNEXPECTED_CALLBACK);
+ METRICS_KEYPHRASE_TRIGGERED_DETECT_UNEXPECTED_CALLBACK,
+ mVoiceInteractionServiceUid);
return;
}
mPerformingSoftwareHotwordDetection = false;
@@ -483,14 +490,15 @@
} catch (SecurityException e) {
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION);
+ METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION,
+ mVoiceInteractionServiceUid);
mSoftwareCallback.onError();
return;
}
saveProximityValueToBundle(result);
HotwordDetectedResult newResult;
try {
- newResult = mHotwordAudioStreamManager.startCopyingAudioStreams(result);
+ newResult = mHotwordAudioStreamCopier.startCopyingAudioStreams(result);
} catch (IOException e) {
// TODO: Write event
mSoftwareCallback.onError();
@@ -512,7 +520,8 @@
}
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED);
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED,
+ mVoiceInteractionServiceUid);
// onRejected isn't allowed here, and we are not expecting it.
}
};
@@ -660,12 +669,14 @@
}
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED);
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED,
+ mVoiceInteractionServiceUid);
if (!mValidatingDspTrigger) {
Slog.i(TAG, "Ignoring #onDetected due to a process restart");
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- METRICS_KEYPHRASE_TRIGGERED_DETECT_UNEXPECTED_CALLBACK);
+ METRICS_KEYPHRASE_TRIGGERED_DETECT_UNEXPECTED_CALLBACK,
+ mVoiceInteractionServiceUid);
return;
}
mValidatingDspTrigger = false;
@@ -675,14 +686,15 @@
Slog.i(TAG, "Ignoring #onDetected due to a SecurityException", e);
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION);
+ METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION,
+ mVoiceInteractionServiceUid);
externalCallback.onError(CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION);
return;
}
saveProximityValueToBundle(result);
HotwordDetectedResult newResult;
try {
- newResult = mHotwordAudioStreamManager.startCopyingAudioStreams(result);
+ newResult = mHotwordAudioStreamCopier.startCopyingAudioStreams(result);
} catch (IOException e) {
// TODO: Write event
externalCallback.onError(CALLBACK_ONDETECTED_STREAM_COPY_ERROR);
@@ -708,12 +720,14 @@
}
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED);
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED,
+ mVoiceInteractionServiceUid);
if (!mValidatingDspTrigger) {
Slog.i(TAG, "Ignoring #onRejected due to a process restart");
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- METRICS_KEYPHRASE_TRIGGERED_REJECT_UNEXPECTED_CALLBACK);
+ METRICS_KEYPHRASE_TRIGGERED_REJECT_UNEXPECTED_CALLBACK,
+ mVoiceInteractionServiceUid);
return;
}
mValidatingDspTrigger = false;
@@ -727,21 +741,20 @@
synchronized (mLock) {
mValidatingDspTrigger = true;
- mRemoteHotwordDetectionService.run(
- service -> {
- // TODO: avoid allocate every time
- mCancellationKeyPhraseDetectionFuture = mScheduledExecutorService.schedule(
- () -> HotwordMetricsLogger
- .writeKeyphraseTriggerEvent(mDetectorType,
- HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_TIMEOUT),
- VALIDATION_TIMEOUT_MILLIS,
- TimeUnit.MILLISECONDS);
- service.detectFromDspSource(
- recognitionEvent,
- recognitionEvent.getCaptureFormat(),
- VALIDATION_TIMEOUT_MILLIS,
- internalCallback);
- });
+ mRemoteHotwordDetectionService.run(service -> {
+ // TODO: avoid allocate every time
+ mCancellationKeyPhraseDetectionFuture = mScheduledExecutorService.schedule(
+ () -> HotwordMetricsLogger.writeKeyphraseTriggerEvent(mDetectorType,
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_TIMEOUT,
+ mVoiceInteractionServiceUid),
+ VALIDATION_TIMEOUT_MILLIS,
+ TimeUnit.MILLISECONDS);
+ service.detectFromDspSource(
+ recognitionEvent,
+ recognitionEvent.getCaptureFormat(),
+ VALIDATION_TIMEOUT_MILLIS,
+ internalCallback);
+ });
}
}
@@ -789,7 +802,8 @@
mCallback.onRejected(new HotwordRejectedResult.Builder().build());
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
- HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED_FROM_RESTART);
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED_FROM_RESTART,
+ mVoiceInteractionServiceUid);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to call #rejected");
}
@@ -835,11 +849,13 @@
private SoundTrigger.KeyphraseRecognitionEvent mRecognitionEvent;
private final HotwordDetectionConnection mHotwordDetectionConnection;
private final IHotwordRecognitionStatusCallback mExternalCallback;
+ private final int mVoiceInteractionServiceUid;
SoundTriggerCallback(IHotwordRecognitionStatusCallback callback,
- HotwordDetectionConnection connection) {
+ HotwordDetectionConnection connection, int uid) {
mHotwordDetectionConnection = connection;
mExternalCallback = callback;
+ mVoiceInteractionServiceUid = uid;
}
@Override
@@ -852,14 +868,16 @@
if (useHotwordDetectionService) {
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP,
- HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER);
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER,
+ mVoiceInteractionServiceUid);
mRecognitionEvent = recognitionEvent;
mHotwordDetectionConnection.detectFromDspSource(
recognitionEvent, mExternalCallback);
} else {
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR,
- HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER);
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER,
+ mVoiceInteractionServiceUid);
mExternalCallback.onKeyphraseDetected(recognitionEvent, null);
}
}
@@ -1014,7 +1032,7 @@
HotwordDetectedResult newResult;
try {
newResult =
- mHotwordAudioStreamManager.startCopyingAudioStreams(
+ mHotwordAudioStreamCopier.startCopyingAudioStreams(
triggerResult);
} catch (IOException e) {
// TODO: Write event
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
index 940aed3..c35d90f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
@@ -16,6 +16,9 @@
package com.android.server.voiceinteraction;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
@@ -47,6 +50,12 @@
HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
private static final int METRICS_INIT_NORMAL_DETECTOR =
HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+ private static final int AUDIO_EGRESS_DSP_DETECTOR =
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+ private static final int AUDIO_EGRESS_SOFTWARE_DETECTOR =
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+ private static final int AUDIO_EGRESS_NORMAL_DETECTOR =
+ HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
private HotwordMetricsLogger() {
// Class only contains static utility functions, and should not be instantiated
@@ -64,28 +73,28 @@
/**
* Logs information related to hotword detection service init result.
*/
- public static void writeServiceInitResultEvent(int detectorType, int result) {
+ public static void writeServiceInitResultEvent(int detectorType, int result, int uid) {
int metricsDetectorType = getInitMetricsDetectorType(detectorType);
FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED,
- metricsDetectorType, result);
+ metricsDetectorType, result, uid);
}
/**
* Logs information related to hotword detection service restarting.
*/
- public static void writeServiceRestartEvent(int detectorType, int reason) {
+ public static void writeServiceRestartEvent(int detectorType, int reason, int uid) {
int metricsDetectorType = getRestartMetricsDetectorType(detectorType);
FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED,
- metricsDetectorType, reason);
+ metricsDetectorType, reason, uid);
}
/**
* Logs information related to keyphrase trigger.
*/
- public static void writeKeyphraseTriggerEvent(int detectorType, int result) {
+ public static void writeKeyphraseTriggerEvent(int detectorType, int result, int uid) {
int metricsDetectorType = getKeyphraseMetricsDetectorType(detectorType);
FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED,
- metricsDetectorType, result);
+ metricsDetectorType, result, uid);
}
/**
@@ -97,6 +106,16 @@
metricsDetectorType, event, uid);
}
+ /**
+ * Logs information related to hotword audio egress events.
+ */
+ public static void writeAudioEgressEvent(int detectorType, int event, int uid,
+ int streamSizeBytes, int bundleSizeBytes, int streamCount) {
+ int metricsDetectorType = getAudioEgressDetectorType(detectorType);
+ FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED,
+ metricsDetectorType, event, uid, streamSizeBytes, bundleSizeBytes, streamCount);
+ }
+
private static int getCreateMetricsDetectorType(int detectorType) {
switch (detectorType) {
case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
@@ -151,4 +170,15 @@
return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__NORMAL_DETECTOR;
}
}
+
+ private static int getAudioEgressDetectorType(int detectorType) {
+ switch (detectorType) {
+ case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
+ return AUDIO_EGRESS_SOFTWARE_DETECTOR;
+ case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
+ return AUDIO_EGRESS_DSP_DETECTOR;
+ default:
+ return AUDIO_EGRESS_NORMAL_DETECTOR;
+ }
+ }
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index f90fbb2..c4f341e 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -711,7 +711,7 @@
Slog.d(TAG, "createSoundTriggerCallbackLocked");
}
return new HotwordDetectionConnection.SoundTriggerCallback(callback,
- mHotwordDetectionConnection);
+ mHotwordDetectionConnection, mInfo.getServiceInfo().applicationInfo.uid);
}
private static ServiceInfo getServiceInfoLocked(@NonNull ComponentName componentName,
@@ -880,5 +880,8 @@
@Override
public void onSessionHidden(VoiceInteractionSessionConnection connection) {
mServiceStub.onSessionHidden();
+ // Notifies visibility change here can cause duplicate events, it is added to make sure
+ // client always get the callback even if session is unexpectedly closed.
+ mServiceStub.setSessionWindowVisible(connection.mToken, false);
}
}
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 7991dfd..1252dc1 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -1569,8 +1569,8 @@
/**
* Returns whether the passing portIndex is available.
- * A port is available if it is active without an enabled profile on it or calling app can
- * activate a new profile on the selected port without any user interaction.
+ * A port is available if it is active without enabled profile on it or
+ * calling app has carrier privilege over the profile installed on the selected port.
* Always returns false if the cardId is a physical card.
*
* @param portIndex is an enumeration of the ports available on the UICC.
diff --git a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
index 2031af2..1930a1c 100644
--- a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
+++ b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
@@ -63,6 +63,7 @@
inner class Listener : TrustListener {
override fun onTrustChanged(
enabled: Boolean,
+ newlyUnlocked: Boolean,
userId: Int,
flags: Int,
trustGrantedMessages: MutableList<String>