Merge "Fix rotation bounds calculation in WindowMagnificationControllerTest"
diff --git a/core/api/current.txt b/core/api/current.txt
index dfbd90c..f989d06 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -4386,6 +4386,7 @@
method @Nullable public android.graphics.Rect getLaunchBounds();
method public int getLaunchDisplayId();
method public boolean getLockTaskMode();
+ method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
method public static android.app.ActivityOptions makeBasic();
method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -4399,6 +4400,7 @@
method public android.app.ActivityOptions setLaunchBounds(@Nullable android.graphics.Rect);
method public android.app.ActivityOptions setLaunchDisplayId(int);
method public android.app.ActivityOptions setLockTaskEnabled(boolean);
+ method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
method public android.os.Bundle toBundle();
method public void update(android.app.ActivityOptions);
field public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index cd5dd42..599f11d 100755
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -440,6 +440,11 @@
method public void onUidImportance(int, int);
}
+ public class ActivityOptions {
+ method public int getLaunchTaskId();
+ method @RequiresPermission("android.permission.START_TASKS_FROM_RECENTS") public void setLaunchTaskId(int);
+ }
+
public class AlarmManager {
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, android.app.PendingIntent, android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, android.app.AlarmManager.OnAlarmListener, android.os.Handler, android.os.WorkSource);
@@ -688,9 +693,11 @@
}
public class BroadcastOptions {
+ method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
method public static android.app.BroadcastOptions makeBasic();
method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
method public void setDontSendToRestrictedApps(boolean);
+ method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppAllowlist(long, int, int, @Nullable String);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long);
method public android.os.Bundle toBundle();
@@ -2292,7 +2299,7 @@
package android.companion {
public final class AssociationRequest implements android.os.Parcelable {
- field public static final String DEVICE_PROFILE_APP_STREAMING = "android.app.role.COMPANION_DEVICE_APP_STREAMING";
+ field @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING) public static final String DEVICE_PROFILE_APP_STREAMING = "android.app.role.COMPANION_DEVICE_APP_STREAMING";
}
public final class CompanionDeviceManager {
@@ -9050,6 +9057,7 @@
public final class PermissionManager {
method public int checkDeviceIdentifierAccess(@Nullable String, @Nullable String, @Nullable String, int, int);
method public int checkPermissionForDataDelivery(@NonNull String, @NonNull android.content.AttributionSource, @Nullable String);
+ method public int checkPermissionForDataDeliveryFromDataSource(@NonNull String, @NonNull android.content.AttributionSource, @Nullable String);
method public int checkPermissionForPreflight(@NonNull String, @NonNull android.content.AttributionSource);
method @NonNull @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public java.util.Set<java.lang.String> getAutoRevokeExemptionGrantedPackages();
method @NonNull @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public java.util.Set<java.lang.String> getAutoRevokeExemptionRequestedPackages();
@@ -9291,6 +9299,7 @@
field public static final String NAMESPACE_SYSTEMUI = "systemui";
field public static final String NAMESPACE_SYSTEM_TIME = "system_time";
field public static final String NAMESPACE_TELEPHONY = "telephony";
+ field public static final String NAMESPACE_TETHERING = "tethering";
field public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
field public static final String NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT = "window_manager_native_boot";
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 372ad9d..e707b03 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -146,7 +146,6 @@
method @NonNull @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS) public static android.app.ActivityOptions makeCustomTaskAnimation(@NonNull android.content.Context, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener);
method public static void setExitTransitionTimeout(long);
method public void setLaunchActivityType(int);
- method public void setLaunchTaskId(int);
method public void setLaunchWindowingMode(int);
method public void setLaunchedFromBubble(boolean);
method public void setTaskAlwaysOnTop(boolean);
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 860224c..a5facd9 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -69,7 +69,7 @@
* {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
* Context.startActivity(Intent, Bundle)} and related methods.
*/
-public class ActivityOptions {
+public class ActivityOptions extends ComponentOptions {
private static final String TAG = "ActivityOptions";
/**
@@ -168,14 +168,6 @@
public static final String KEY_SPLASH_SCREEN_THEME = "android.activity.splashScreenTheme";
/**
- * PendingIntent caller allows activity start even if PendingIntent creator is in background.
- * This only works if the PendingIntent caller is allowed to start background activities,
- * for example if it's in the foreground, or has BAL permission.
- * @hide
- */
- public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED =
- "android.pendingIntent.backgroundActivityAllowed";
- /**
* Callback for when the last frame of the animation is played.
* @hide
*/
@@ -389,12 +381,6 @@
/** @hide */
public static final int ANIM_REMOTE_ANIMATION = 13;
- /**
- * Default value for KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED.
- * @hide
- **/
- public static final boolean PENDING_INTENT_BAL_ALLOWED_DEFAULT = true;
-
private String mPackageName;
private Rect mLaunchBounds;
private int mAnimationType = ANIM_UNDEFINED;
@@ -446,7 +432,6 @@
private String mSplashScreenThemeResName;
@SplashScreen.SplashScreenStyle
private int mSplashScreenStyle;
- private boolean mPendingIntentBalAllowed = PENDING_INTENT_BAL_ALLOWED_DEFAULT;
private boolean mRemoveWithTaskOrganizer;
private boolean mLaunchedFromBubble;
private boolean mTransientLaunch;
@@ -1096,13 +1081,12 @@
}
private ActivityOptions() {
+ super();
}
/** @hide */
public ActivityOptions(Bundle opts) {
- // If the remote side sent us bad parcelables, they won't get the
- // results they want, which is their loss.
- opts.setDefusable(true);
+ super(opts);
mPackageName = opts.getString(KEY_PACKAGE_NAME);
try {
@@ -1200,8 +1184,6 @@
mRemoteTransition = opts.getParcelable(KEY_REMOTE_TRANSITION);
mOverrideTaskTransition = opts.getBoolean(KEY_OVERRIDE_TASK_TRANSITION);
mSplashScreenThemeResName = opts.getString(KEY_SPLASH_SCREEN_THEME);
- mPendingIntentBalAllowed = opts.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
- PENDING_INTENT_BAL_ALLOWED_DEFAULT);
mRemoveWithTaskOrganizer = opts.getBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER);
mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE);
mTransientLaunch = opts.getBoolean(KEY_TRANSIENT_LAUNCH);
@@ -1426,24 +1408,6 @@
}
/**
- * Set PendingIntent activity is allowed to be started in the background if the caller
- * can start background activities.
- * @hide
- */
- public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
- mPendingIntentBalAllowed = allowed;
- }
-
- /**
- * Get PendingIntent activity is allowed to be started in the background if the caller
- * can start background activities.
- * @hide
- */
- public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
- return mPendingIntentBalAllowed;
- }
-
- /**
* Sets whether the activity is to be launched into LockTask mode.
*
* Use this option to start an activity in LockTask mode. Note that only apps permitted by
@@ -1565,7 +1529,8 @@
* Sets the task the activity will be launched in.
* @hide
*/
- @TestApi
+ @RequiresPermission(START_TASKS_FROM_RECENTS)
+ @SystemApi
public void setLaunchTaskId(int taskId) {
mLaunchTaskId = taskId;
}
@@ -1573,6 +1538,7 @@
/**
* @hide
*/
+ @SystemApi
public int getLaunchTaskId() {
return mLaunchTaskId;
}
@@ -1868,8 +1834,9 @@
* object; you must not modify it, but can supply it to the startActivity
* methods that take an options Bundle.
*/
+ @Override
public Bundle toBundle() {
- Bundle b = new Bundle();
+ Bundle b = super.toBundle();
if (mPackageName != null) {
b.putString(KEY_PACKAGE_NAME, mPackageName);
}
@@ -2016,7 +1983,6 @@
if (mSplashScreenThemeResName != null && !mSplashScreenThemeResName.isEmpty()) {
b.putString(KEY_SPLASH_SCREEN_THEME, mSplashScreenThemeResName);
}
- b.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, mPendingIntentBalAllowed);
if (mRemoveWithTaskOrganizer) {
b.putBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER, mRemoveWithTaskOrganizer);
}
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 4e19abf..5b8cc70 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -34,7 +34,7 @@
* {@hide}
*/
@SystemApi
-public class BroadcastOptions {
+public class BroadcastOptions extends ComponentOptions {
private long mTemporaryAppAllowlistDuration;
private @TempAllowListType int mTemporaryAppAllowlistType;
private @ReasonCode int mTemporaryAppAllowlistReasonCode;
@@ -43,7 +43,6 @@
private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
private boolean mDontSendToRestrictedApps = false;
private boolean mAllowBackgroundActivityStarts;
- private boolean mPendingIntentBalAllowed = ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT;
/**
* How long to temporarily put an app on the power allowlist when executing this broadcast
@@ -80,16 +79,6 @@
"android:broadcast.dontSendToRestrictedApps";
/**
- * PendingIntent caller allows activity start even if PendingIntent creator is in background.
- * This only works if the PendingIntent caller is allowed to start background activities,
- * for example if it's in the foreground, or has BAL permission.
- * TODO: Merge it with ActivityOptions.
- * @hide
- */
- public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED =
- "android.pendingIntent.backgroundActivityAllowed";
-
- /**
* Corresponds to {@link #setBackgroundActivityStartsAllowed}.
*/
private static final String KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS =
@@ -119,12 +108,14 @@
}
private BroadcastOptions() {
+ super();
resetTemporaryAppAllowlist();
}
/** @hide */
@TestApi
public BroadcastOptions(@NonNull Bundle opts) {
+ super(opts);
// Match the logic in toBundle().
if (opts.containsKey(KEY_TEMPORARY_APP_ALLOWLIST_DURATION)) {
mTemporaryAppAllowlistDuration = opts.getLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION);
@@ -141,8 +132,6 @@
mDontSendToRestrictedApps = opts.getBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, false);
mAllowBackgroundActivityStarts = opts.getBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS,
false);
- mPendingIntentBalAllowed = opts.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
- ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT);
}
/**
@@ -204,6 +193,26 @@
}
/**
+ * Set PendingIntent activity is allowed to be started in the background if the caller
+ * can start background activities.
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
+ public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
+ super.setPendingIntentBackgroundActivityLaunchAllowed(allowed);
+ }
+
+ /**
+ * Get PendingIntent activity is allowed to be started in the background if the caller
+ * can start background activities.
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
+ public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
+ return super.isPendingIntentBackgroundActivityLaunchAllowed();
+ }
+
+ /**
* Return {@link #setTemporaryAppAllowlist}.
* @hide
*/
@@ -314,26 +323,6 @@
}
/**
- * Set PendingIntent activity is allowed to be started in the background if the caller
- * can start background activities.
- * TODO: Merge it with ActivityOptions.
- * @hide
- */
- public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
- mPendingIntentBalAllowed = allowed;
- }
-
- /**
- * Get PendingIntent activity is allowed to be started in the background if the caller
- * can start background activities.
- * TODO: Merge it with ActivityOptions.
- * @hide
- */
- public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
- return mPendingIntentBalAllowed;
- }
-
- /**
* Returns the created options as a Bundle, which can be passed to
* {@link android.content.Context#sendBroadcast(android.content.Intent)
* Context.sendBroadcast(Intent)} and related methods.
@@ -341,8 +330,9 @@
* object; you must not modify it, but can supply it to the sendBroadcast
* methods that take an options Bundle.
*/
+ @Override
public Bundle toBundle() {
- Bundle b = new Bundle();
+ Bundle b = super.toBundle();
if (isTemporaryAppAllowlistSet()) {
b.putLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION, mTemporaryAppAllowlistDuration);
b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE, mTemporaryAppAllowlistType);
@@ -361,8 +351,6 @@
if (mAllowBackgroundActivityStarts) {
b.putBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS, true);
}
- // TODO: Add API for BroadcastOptions and have a shared base class with ActivityOptions.
- b.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, mPendingIntentBalAllowed);
return b.isEmpty() ? null : b;
}
}
diff --git a/core/java/android/app/ComponentOptions.java b/core/java/android/app/ComponentOptions.java
new file mode 100644
index 0000000..d50a73a
--- /dev/null
+++ b/core/java/android/app/ComponentOptions.java
@@ -0,0 +1,76 @@
+/*
+ * 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 android.app;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+public class ComponentOptions {
+
+ /**
+ * Default value for KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED.
+ * @hide
+ **/
+ public static final boolean PENDING_INTENT_BAL_ALLOWED_DEFAULT = true;
+
+ /**
+ * PendingIntent caller allows activity start even if PendingIntent creator is in background.
+ * This only works if the PendingIntent caller is allowed to start background activities,
+ * for example if it's in the foreground, or has BAL permission.
+ * @hide
+ */
+ public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED =
+ "android.pendingIntent.backgroundActivityAllowed";
+
+ private boolean mPendingIntentBalAllowed = PENDING_INTENT_BAL_ALLOWED_DEFAULT;
+
+ ComponentOptions() {
+ }
+
+ ComponentOptions(Bundle opts) {
+ // If the remote side sent us bad parcelables, they won't get the
+ // results they want, which is their loss.
+ opts.setDefusable(true);
+ setPendingIntentBackgroundActivityLaunchAllowed(
+ opts.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
+ PENDING_INTENT_BAL_ALLOWED_DEFAULT));
+ }
+
+ /**
+ * Set PendingIntent activity is allowed to be started in the background if the caller
+ * can start background activities.
+ */
+ public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
+ mPendingIntentBalAllowed = allowed;
+ }
+
+ /**
+ * Get PendingIntent activity is allowed to be started in the background if the caller
+ * can start background activities.
+ */
+ public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
+ return mPendingIntentBalAllowed;
+ }
+
+ public Bundle toBundle() {
+ Bundle b = new Bundle();
+ b.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, mPendingIntentBalAllowed);
+ return b;
+ }
+}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 95ba523..1312454 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -115,7 +115,6 @@
ParceledListSlice getNotificationChannelGroups(String pkg);
boolean onlyHasDefaultChannel(String pkg, int uid);
boolean areChannelsBypassingDnd();
- int getAppsBypassingDndCount(int uid);
ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int userId);
boolean isPackagePaused(String pkg);
void deleteNotificationHistoryItem(String pkg, int uid, long postedTime);
diff --git a/core/java/android/companion/Association.java b/core/java/android/companion/Association.java
index b060ce2..7cea33d 100644
--- a/core/java/android/companion/Association.java
+++ b/core/java/android/companion/Association.java
@@ -15,219 +15,223 @@
*/
package android.companion;
+import static android.companion.DeviceId.TYPE_MAC_ADDRESS;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.Parcel;
import android.os.Parcelable;
-import com.android.internal.util.DataClass;
-
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* A record indicating that a device with a given address was confirmed by the user to be
* associated to a given companion app
*
* @hide
+ * TODO(b/1979395): un-hide and rename to AssociationInfo when implementing public APIs that use
+ * this class.
*/
-@DataClass(genEqualsHashCode = true, genToString = true, genHiddenConstructor = true)
public final class Association implements Parcelable {
+ /**
+ * A unique ID of this Association record.
+ * Disclosed to the clients (ie. companion applications) for referring to this record (eg. in
+ * {@code disassociate()} API call).
+ */
+ private final int mAssociationId;
private final @UserIdInt int mUserId;
- private final @NonNull String mDeviceMacAddress;
private final @NonNull String mPackageName;
+
+ private final @NonNull List<DeviceId> mDeviceIds;
private final @Nullable String mDeviceProfile;
- private final boolean mNotifyOnDeviceNearby;
+
+ private final boolean mManagedByCompanionApp;
+ private boolean mNotifyOnDeviceNearby;
private final long mTimeApprovedMs;
+ /**
+ * Creates a new Association.
+ * Only to be used by the CompanionDeviceManagerService.
+ *
+ * @hide
+ */
+ public Association(int associationId, @UserIdInt int userId, @NonNull String packageName,
+ @NonNull List<DeviceId> deviceIds, @Nullable String deviceProfile,
+ boolean managedByCompanionApp, boolean notifyOnDeviceNearby, long timeApprovedMs) {
+ if (associationId <= 0) {
+ throw new IllegalArgumentException("Association ID should be greater than 0");
+ }
+ validateDeviceIds(deviceIds);
+
+ mAssociationId = associationId;
+
+ mUserId = userId;
+ mPackageName = packageName;
+
+ mDeviceProfile = deviceProfile;
+ mDeviceIds = new ArrayList<>(deviceIds);
+
+ mManagedByCompanionApp = managedByCompanionApp;
+ mNotifyOnDeviceNearby = notifyOnDeviceNearby;
+ mTimeApprovedMs = timeApprovedMs;
+ }
+
+ /**
+ * @return the unique ID of this association record.
+ */
+ public int getAssociationId() {
+ return mAssociationId;
+ }
+
/** @hide */
public int getUserId() {
return mUserId;
}
- private String timeApprovedMsToString() {
- return new Date(mTimeApprovedMs).toString();
- }
-
-
-
- // Code below generated by codegen v1.0.22.
- //
- // DO NOT MODIFY!
- // CHECKSTYLE:OFF Generated code
- //
- // To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/companion/Association.java
- //
- // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
- // Settings > Editor > Code Style > Formatter Control
- //@formatter:off
-
-
- /**
- * Creates a new Association.
- *
- * @hide
- */
- @DataClass.Generated.Member
- public Association(
- @UserIdInt int userId,
- @NonNull String deviceMacAddress,
- @NonNull String packageName,
- @Nullable String deviceProfile,
- boolean notifyOnDeviceNearby,
- long timeApprovedMs) {
- this.mUserId = userId;
- com.android.internal.util.AnnotationValidations.validate(
- UserIdInt.class, null, mUserId);
- this.mDeviceMacAddress = deviceMacAddress;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mDeviceMacAddress);
- this.mPackageName = packageName;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mPackageName);
- this.mDeviceProfile = deviceProfile;
- this.mNotifyOnDeviceNearby = notifyOnDeviceNearby;
- this.mTimeApprovedMs = timeApprovedMs;
-
- // onConstructed(); // You can define this method to get a callback
- }
-
- @DataClass.Generated.Member
- public @NonNull String getDeviceMacAddress() {
- return mDeviceMacAddress;
- }
-
- @DataClass.Generated.Member
+ /** @hide */
public @NonNull String getPackageName() {
return mPackageName;
}
- @DataClass.Generated.Member
+ /**
+ * @return list of the device's IDs. At any time a device has at least 1 ID.
+ */
+ public @NonNull List<DeviceId> getDeviceIds() {
+ return Collections.unmodifiableList(mDeviceIds);
+ }
+
+ /**
+ * @param type type of the ID.
+ * @return ID of the type if the device has such ID, {@code null} otherwise.
+ */
+ public @Nullable String getIdOfType(@NonNull String type) {
+ for (int i = mDeviceIds.size() - 1; i >= 0; i--) {
+ final DeviceId id = mDeviceIds.get(i);
+ if (Objects.equals(mDeviceIds.get(i).getType(), type)) return id.getValue();
+ }
+ return null;
+ }
+
+ /** @hide */
+ public @NonNull String getDeviceMacAddress() {
+ return Objects.requireNonNull(getIdOfType(TYPE_MAC_ADDRESS),
+ "MAC address of this device is not specified.");
+ }
+
+ /**
+ * @return the profile of the device.
+ */
public @Nullable String getDeviceProfile() {
return mDeviceProfile;
}
- @DataClass.Generated.Member
+ /** @hide */
+ public boolean isManagedByCompanionApp() {
+ return mManagedByCompanionApp;
+ }
+
+ /**
+ * Should only be used by the CdmService.
+ * @hide
+ */
+ public void setNotifyOnDeviceNearby(boolean notifyOnDeviceNearby) {
+ mNotifyOnDeviceNearby = notifyOnDeviceNearby;
+ }
+
+ /** @hide */
public boolean isNotifyOnDeviceNearby() {
return mNotifyOnDeviceNearby;
}
- @DataClass.Generated.Member
+ /** @hide */
public long getTimeApprovedMs() {
return mTimeApprovedMs;
}
- @Override
- @DataClass.Generated.Member
- public String toString() {
- // You can override field toString logic by defining methods like:
- // String fieldNameToString() { ... }
-
- return "Association { " +
- "userId = " + mUserId + ", " +
- "deviceMacAddress = " + mDeviceMacAddress + ", " +
- "packageName = " + mPackageName + ", " +
- "deviceProfile = " + mDeviceProfile + ", " +
- "notifyOnDeviceNearby = " + mNotifyOnDeviceNearby + ", " +
- "timeApprovedMs = " + timeApprovedMsToString() +
- " }";
+ /** @hide */
+ public boolean belongsToPackage(@UserIdInt int userId, String packageName) {
+ return mUserId == userId && Objects.equals(mPackageName, packageName);
}
@Override
- @DataClass.Generated.Member
- public boolean equals(@Nullable Object o) {
- // You can override field equality logic by defining either of the methods like:
- // boolean fieldNameEquals(Association other) { ... }
- // boolean fieldNameEquals(FieldType otherValue) { ... }
+ public String toString() {
+ return "Association{"
+ + "mAssociationId=" + mAssociationId
+ + ", mUserId=" + mUserId
+ + ", mPackageName='" + mPackageName + '\''
+ + ", mDeviceIds=" + mDeviceIds
+ + ", mDeviceProfile='" + mDeviceProfile + '\''
+ + ", mManagedByCompanionApp=" + mManagedByCompanionApp
+ + ", mNotifyOnDeviceNearby=" + mNotifyOnDeviceNearby
+ + ", mTimeApprovedMs=" + new Date(mTimeApprovedMs)
+ + '}';
+ }
+ @Override
+ public boolean equals(Object o) {
if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- @SuppressWarnings("unchecked")
- Association that = (Association) o;
- //noinspection PointlessBooleanExpression
- return true
+ if (!(o instanceof Association)) return false;
+ final Association that = (Association) o;
+ return mAssociationId == that.mAssociationId
&& mUserId == that.mUserId
- && Objects.equals(mDeviceMacAddress, that.mDeviceMacAddress)
+ && mManagedByCompanionApp == that.mManagedByCompanionApp
+ && mNotifyOnDeviceNearby == that.mNotifyOnDeviceNearby
+ && mTimeApprovedMs == that.mTimeApprovedMs
&& Objects.equals(mPackageName, that.mPackageName)
&& Objects.equals(mDeviceProfile, that.mDeviceProfile)
- && mNotifyOnDeviceNearby == that.mNotifyOnDeviceNearby
- && mTimeApprovedMs == that.mTimeApprovedMs;
+ && Objects.equals(mDeviceIds, that.mDeviceIds);
}
@Override
- @DataClass.Generated.Member
public int hashCode() {
- // You can override field hashCode logic by defining methods like:
- // int fieldNameHashCode() { ... }
-
- int _hash = 1;
- _hash = 31 * _hash + mUserId;
- _hash = 31 * _hash + Objects.hashCode(mDeviceMacAddress);
- _hash = 31 * _hash + Objects.hashCode(mPackageName);
- _hash = 31 * _hash + Objects.hashCode(mDeviceProfile);
- _hash = 31 * _hash + Boolean.hashCode(mNotifyOnDeviceNearby);
- _hash = 31 * _hash + Long.hashCode(mTimeApprovedMs);
- return _hash;
+ return Objects.hash(mAssociationId, mUserId, mPackageName, mDeviceIds, mDeviceProfile,
+ mManagedByCompanionApp, mNotifyOnDeviceNearby, mTimeApprovedMs);
}
@Override
- @DataClass.Generated.Member
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- // You can override field parcelling by defining methods like:
- // void parcelFieldName(Parcel dest, int flags) { ... }
+ public int describeContents() {
+ return 0;
+ }
- byte flg = 0;
- if (mNotifyOnDeviceNearby) flg |= 0x10;
- if (mDeviceProfile != null) flg |= 0x8;
- dest.writeByte(flg);
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mAssociationId);
+
dest.writeInt(mUserId);
- dest.writeString(mDeviceMacAddress);
dest.writeString(mPackageName);
- if (mDeviceProfile != null) dest.writeString(mDeviceProfile);
+
+ dest.writeParcelableList(mDeviceIds, 0);
+ dest.writeString(mDeviceProfile);
+
+ dest.writeBoolean(mManagedByCompanionApp);
+ dest.writeBoolean(mNotifyOnDeviceNearby);
dest.writeLong(mTimeApprovedMs);
}
- @Override
- @DataClass.Generated.Member
- public int describeContents() { return 0; }
+ private Association(@NonNull Parcel in) {
+ mAssociationId = in.readInt();
- /** @hide */
- @SuppressWarnings({"unchecked", "RedundantCast"})
- @DataClass.Generated.Member
- /* package-private */ Association(@NonNull Parcel in) {
- // You can override field unparcelling by defining methods like:
- // static FieldType unparcelFieldName(Parcel in) { ... }
+ mUserId = in.readInt();
+ mPackageName = in.readString();
- byte flg = in.readByte();
- boolean notifyOnDeviceNearby = (flg & 0x10) != 0;
- int userId = in.readInt();
- String deviceMacAddress = in.readString();
- String packageName = in.readString();
- String deviceProfile = (flg & 0x8) == 0 ? null : in.readString();
- long timeApprovedMs = in.readLong();
+ mDeviceIds = in.readParcelableList(new ArrayList<>(), DeviceId.class.getClassLoader());
+ mDeviceProfile = in.readString();
- this.mUserId = userId;
- com.android.internal.util.AnnotationValidations.validate(
- UserIdInt.class, null, mUserId);
- this.mDeviceMacAddress = deviceMacAddress;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mDeviceMacAddress);
- this.mPackageName = packageName;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mPackageName);
- this.mDeviceProfile = deviceProfile;
- this.mNotifyOnDeviceNearby = notifyOnDeviceNearby;
- this.mTimeApprovedMs = timeApprovedMs;
-
- // onConstructed(); // You can define this method to get a callback
+ mManagedByCompanionApp = in.readBoolean();
+ mNotifyOnDeviceNearby = in.readBoolean();
+ mTimeApprovedMs = in.readLong();
}
- @DataClass.Generated.Member
- public static final @NonNull Parcelable.Creator<Association> CREATOR
- = new Parcelable.Creator<Association>() {
+ public static final Parcelable.Creator<Association> CREATOR =
+ new Parcelable.Creator<Association>() {
@Override
public Association[] newArray(int size) {
return new Association[size];
@@ -239,16 +243,18 @@
}
};
- @DataClass.Generated(
- time = 1611795283642L,
- codegenVersion = "1.0.22",
- sourceFile = "frameworks/base/core/java/android/companion/Association.java",
- inputSignatures = "private final @android.annotation.UserIdInt int mUserId\nprivate final @android.annotation.NonNull java.lang.String mDeviceMacAddress\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate final boolean mNotifyOnDeviceNearby\nprivate final long mTimeApprovedMs\npublic int getUserId()\nprivate java.lang.String timeApprovedMsToString()\nclass Association extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstructor=true)")
- @Deprecated
- private void __metadata() {}
+ private static void validateDeviceIds(@NonNull List<DeviceId> ids) {
+ if (ids.isEmpty()) throw new IllegalArgumentException("Device must have at least 1 id.");
-
- //@formatter:on
- // End of generated code
-
+ // Make sure none of the IDs are null, and they all have different types.
+ final Set<String> types = new HashSet<>(ids.size());
+ for (int i = ids.size() - 1; i >= 0; i--) {
+ final DeviceId deviceId = ids.get(i);
+ if (deviceId == null) throw new IllegalArgumentException("DeviceId must not be null");
+ if (!types.add(deviceId.getType())) {
+ throw new IllegalArgumentException(
+ "DeviceId cannot have multiple IDs of the same type");
+ }
+ }
+ }
}
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index 36ea0b9..24d1248 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -18,8 +18,10 @@
import static com.android.internal.util.CollectionUtils.emptyIfNull;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.StringDef;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -53,7 +55,8 @@
genHiddenGetters = true,
genParcelable = true,
genHiddenConstructor = true,
- genBuilder = false)
+ genBuilder = false,
+ genConstDefs = false)
public final class AssociationRequest implements Parcelable {
private static final String LOG_TAG = AssociationRequest.class.getSimpleName();
@@ -86,6 +89,7 @@
* @see AssociationRequest.Builder#setDeviceProfile
* @hide
*/
+ @RequiresPermission(Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING)
@SystemApi
public static final String DEVICE_PROFILE_APP_STREAMING =
"android.app.role.COMPANION_DEVICE_APP_STREAMING";
@@ -494,10 +498,10 @@
};
@DataClass.Generated(
- time = 1633625630103L,
+ time = 1634716126923L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/companion/AssociationRequest.java",
- inputSignatures = "private static final java.lang.String LOG_TAG\npublic static final java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.SystemApi java.lang.String DEVICE_PROFILE_APP_STREAMING\nprivate boolean mSingleDevice\nprivate @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.String mCallingPackage\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate long mCreationTime\nprivate boolean mSkipPrompt\nprivate void onConstructed()\npublic void setCallingPackage(java.lang.String)\npublic void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic void setSkipPrompt(boolean)\npublic @android.compat.annotation.UnsupportedAppUsage boolean isSingleDevice()\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genHiddenConstructor=true, genBuilder=false)")
+ inputSignatures = "private static final java.lang.String LOG_TAG\npublic static final java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.RequiresPermission @android.annotation.SystemApi java.lang.String DEVICE_PROFILE_APP_STREAMING\nprivate boolean mSingleDevice\nprivate @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.String mCallingPackage\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate long mCreationTime\nprivate boolean mSkipPrompt\nprivate void onConstructed()\npublic void setCallingPackage(java.lang.String)\npublic void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic void setSkipPrompt(boolean)\npublic @android.compat.annotation.UnsupportedAppUsage boolean isSingleDevice()\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genHiddenConstructor=true, genBuilder=false, genConstDefs=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/companion/DeviceId.java b/core/java/android/companion/DeviceId.java
new file mode 100644
index 0000000..5deed1a
--- /dev/null
+++ b/core/java/android/companion/DeviceId.java
@@ -0,0 +1,127 @@
+/*
+ * 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 android.companion;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * The class represents free-form ID of a companion device.
+ *
+ * Since companion devices may have multiple IDs of different type at the same time
+ * (eg. a MAC address and a Serial Number), this class not only stores the ID itself, it also stores
+ * the type of the ID.
+ * Both the type of the ID and its actual value are represented as {@link String}-s.
+ *
+ * Examples of device IDs:
+ * - "mac_address: f0:18:98:b3:fd:2e"
+ * - "ip_address: 128.121.35.200"
+ * - "imei: 352932100034923 / 44"
+ * - "serial_number: 96141FFAZ000B7"
+ * - "meid_hex: 35293210003492"
+ * - "meid_dic: 08918 92240 0001 3548"
+ *
+ * @hide
+ * TODO(b/1979395): un-hide when implementing public APIs that use this class.
+ */
+public final class DeviceId implements Parcelable {
+ public static final String TYPE_MAC_ADDRESS = "mac_address";
+
+ private final @NonNull String mType;
+ private final @NonNull String mValue;
+
+ /**
+ * @param type type of the ID. Non-empty. Max length - 16 characters.
+ * @param value the ID. Non-empty. Max length - 48 characters.
+ * @throws IllegalArgumentException if either {@param type} or {@param value} is empty or
+ * exceeds its max allowed length.
+ */
+ public DeviceId(@NonNull String type, @NonNull String value) {
+ if (type.isEmpty() || value.isEmpty()) {
+ throw new IllegalArgumentException("'type' and 'value' should not be empty");
+ }
+ this.mType = type;
+ this.mValue = value;
+ }
+
+ /**
+ * @return the type of the ID.
+ */
+ public @NonNull String getType() {
+ return mType;
+ }
+
+ /**
+ * @return the ID.
+ */
+ public @NonNull String getValue() {
+ return mValue;
+ }
+
+ @Override
+ public String toString() {
+ return "DeviceId{"
+ + "type='" + mType + '\''
+ + ", value='" + mValue + '\''
+ + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DeviceId)) return false;
+ DeviceId deviceId = (DeviceId) o;
+ return Objects.equals(mType, deviceId.mType) && Objects.equals(mValue,
+ deviceId.mValue);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mType, mValue);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mType);
+ dest.writeString(mValue);
+ }
+
+ private DeviceId(@NonNull Parcel in) {
+ mType = in.readString();
+ mValue = in.readString();
+ }
+
+ public static final @NonNull Creator<DeviceId> CREATOR = new Creator<DeviceId>() {
+ @Override
+ public DeviceId createFromParcel(@NonNull Parcel in) {
+ return new DeviceId(in);
+ }
+
+ @Override
+ public DeviceId[] newArray(int size) {
+ return new DeviceId[size];
+ }
+ };
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index dc37882..cfd3417 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3336,7 +3336,11 @@
* Service will call {@link android.app.Service#startForeground(int, android.app.Notification)
* startForeground(int, android.app.Notification)} once it begins running. The service is given
* an amount of time comparable to the ANR interval to do this, otherwise the system
- * will automatically stop the service and declare the app ANR.
+ * will automatically crash the process, in which case an internal exception
+ * {@code ForegroundServiceDidNotStartInTimeException} is logged on logcat on devices
+ * running SDK Version {@link android.os.Build.VERSION_CODES#S} or later. On older Android
+ * versions, an internal exception {@code RemoteServiceException} is logged instead, with
+ * a corresponding message.
*
* <p>Unlike the ordinary {@link #startService(Intent)}, this method can be used
* at any time, regardless of whether the app hosting the service is in a foreground
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index db9d4e2..d4c9ade 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -219,6 +219,39 @@
/**
* Checks whether a given data access chain described by the given {@link AttributionSource}
+ * has a given permission. Call this method if you are the datasource which would not blame you
+ * for access to the data since you are the data.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * point where you will deliver the permission protected data to clients.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use {@link #checkPermissionForPreflight(String, AttributionSource)}
+ * to determine if the app has or may have location permission (if app has only foreground
+ * location the grant state depends on the app's fg/gb state) and this check will not
+ * leave a trace that permission protected data was delivered. When you are about to
+ * deliver the location data to a registered listener you should use this method which
+ * will evaluate the permission access based on the current fg/bg state of the app and
+ * leave a record that the data was accessed.
+ *
+ * @param permission The permission to check.
+ * @param attributionSource the permission identity
+ * @param message A message describing the reason the permission was checked
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
+ *
+ * @see #checkPermissionForPreflight(String, AttributionSource)
+ */
+ @PermissionCheckerManager.PermissionResult
+ public int checkPermissionForDataDeliveryFromDataSource(@NonNull String permission,
+ @NonNull AttributionSource attributionSource, @Nullable String message) {
+ return PermissionChecker.checkPermissionForDataDeliveryFromDataSource(mContext, permission,
+ PermissionChecker.PID_UNKNOWN, attributionSource, message);
+ }
+
+ /**
+ * Checks whether a given data access chain described by the given {@link AttributionSource}
* has a given permission.
*
* <strong>NOTE:</strong> Use this method only for permission checks at the
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 1322682..54b87ab7 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -189,6 +189,14 @@
public static final String NAMESPACE_CAPTIVEPORTALLOGIN = "captive_portal_login";
/**
+ * Namespace for Tethering module.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_TETHERING = "tethering";
+
+ /**
* Namespace for content capture feature used by on-device machine intelligence
* to provide suggestions in a privacy-safe manner.
*
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 93061ee..9d4a249 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -15429,27 +15429,9 @@
*/
public static int getInt(ContentResolver cr, String name, int def) {
String v = getString(cr, name);
- final boolean isQueryForDeviceProvision = name.equals(DEVICE_PROVISIONED);
try {
- // TODO(b/197879371): remove the extra logging after bug is fixed
- final int result;
- if (v != null) {
- result = Integer.parseInt(v);
- if (isQueryForDeviceProvision) {
- Log.w(TAG, "Found settings value for provision. Returning " + result);
- }
- } else {
- result = def;
- if (isQueryForDeviceProvision) {
- Log.w(TAG, "Missing settings value for provision. Returning " + result);
- }
- }
- return result;
+ return v != null ? Integer.parseInt(v) : def;
} catch (NumberFormatException e) {
- if (isQueryForDeviceProvision) {
- Log.w(TAG, "Wrong settings value for provision. Found: " + v
- + ". Returning " + v);
- }
return def;
}
}
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 4004148..66188cd 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -139,6 +139,33 @@
this.groupKey = groupKey();
}
+ /**
+ * @hide
+ */
+ public static int getUidFromKey(@NonNull String key) {
+ String[] parts = key.split("\\|");
+ if (parts.length >= 5) {
+ try {
+ int uid = Integer.parseInt(parts[4]);
+ return uid;
+ } catch (NumberFormatException e) {
+ return -1;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * @hide
+ */
+ public static String getPkgFromKey(@NonNull String key) {
+ String[] parts = key.split("\\|");
+ if (parts.length >= 2) {
+ return parts[1];
+ }
+ return null;
+ }
+
private String key() {
String sbnKey = user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid;
if (overrideGroupKey != null && getNotification().isGroupSummary()) {
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 30e4a23..88818b6 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -2044,7 +2044,11 @@
/**
* Registers a callback that will be notified when visible activities have been changed.
*
- * @param executor The handler to receive the callback.
+ * Note: The {@link VisibleActivityCallback#onVisible(VisibleActivityInfo)} will be called
+ * immediately with current visible activities when the callback is registered for the first
+ * time. If the callback is already registered, this method does nothing.
+ *
+ * @param executor The executor which will be used to invoke the callback.
* @param callback The callback to receive the response.
*
* @throws IllegalStateException if calling this method before onCreate().
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 009afce..e023ed5 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -696,7 +696,7 @@
@Override
public void finishComposingText() {
if (mServedInputConnection != null) {
- mServedInputConnection.finishComposingText();
+ mServedInputConnection.finishComposingTextFromImm();
}
}
@@ -919,7 +919,7 @@
mRestartOnNextWindowFocus = true;
// Note that finishComposingText() is allowed to run
// even when we are not active.
- mFallbackInputConnection.finishComposingText();
+ mFallbackInputConnection.finishComposingTextFromImm();
}
// Check focus again in case that "onWindowFocus" is called before
// handling this message.
diff --git a/core/java/com/android/internal/inputmethod/IInputContextInvoker.java b/core/java/com/android/internal/inputmethod/IInputContextInvoker.java
index 2fde981..001e304 100644
--- a/core/java/com/android/internal/inputmethod/IInputContextInvoker.java
+++ b/core/java/com/android/internal/inputmethod/IInputContextInvoker.java
@@ -57,9 +57,14 @@
return new IInputContextInvoker(inputContext);
}
+ @NonNull
+ InputConnectionCommandHeader createHeader() {
+ return new InputConnectionCommandHeader();
+ }
+
/**
- * Invokes {@link IInputContext#getTextAfterCursor(int, int,
- * com.android.internal.inputmethod.ICharSequenceResultCallback)}.
+ * Invokes {@link IInputContext#getTextAfterCursor(InputConnectionCommandHeader, int, int,
+ * AndroidFuture)}.
*
* @param length {@code length} parameter to be passed.
* @param flags {@code flags} parameter to be passed.
@@ -71,7 +76,7 @@
public AndroidFuture<CharSequence> getTextAfterCursor(int length, int flags) {
final AndroidFuture<CharSequence> future = new AndroidFuture<>();
try {
- mIInputContext.getTextAfterCursor(length, flags, future);
+ mIInputContext.getTextAfterCursor(createHeader(), length, flags, future);
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -79,7 +84,8 @@
}
/**
- * Invokes {@link IInputContext#getTextBeforeCursor(int, int, ICharSequenceResultCallback)}.
+ * Invokes {@link IInputContext#getTextBeforeCursor(InputConnectionCommandHeader, int, int,
+ * AndroidFuture)}.
*
* @param length {@code length} parameter to be passed.
* @param flags {@code flags} parameter to be passed.
@@ -91,7 +97,7 @@
public AndroidFuture<CharSequence> getTextBeforeCursor(int length, int flags) {
final AndroidFuture<CharSequence> future = new AndroidFuture<>();
try {
- mIInputContext.getTextBeforeCursor(length, flags, future);
+ mIInputContext.getTextBeforeCursor(createHeader(), length, flags, future);
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -99,7 +105,8 @@
}
/**
- * Invokes {@link IInputContext#getSelectedText(int, ICharSequenceResultCallback)}.
+ * Invokes
+ * {@link IInputContext#getSelectedText(InputConnectionCommandHeader, int, AndroidFuture)}.
*
* @param flags {@code flags} parameter to be passed.
* @return {@link AndroidFuture<CharSequence>} that can be used to retrieve the invocation
@@ -110,7 +117,7 @@
public AndroidFuture<CharSequence> getSelectedText(int flags) {
final AndroidFuture<CharSequence> future = new AndroidFuture<>();
try {
- mIInputContext.getSelectedText(flags, future);
+ mIInputContext.getSelectedText(createHeader(), flags, future);
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -119,7 +126,8 @@
/**
* Invokes
- * {@link IInputContext#getSurroundingText(int, int, int, ISurroundingTextResultCallback)}.
+ * {@link IInputContext#getSurroundingText(InputConnectionCommandHeader, int, int, int,
+ * AndroidFuture)}.
*
* @param beforeLength {@code beforeLength} parameter to be passed.
* @param afterLength {@code afterLength} parameter to be passed.
@@ -133,7 +141,8 @@
int flags) {
final AndroidFuture<SurroundingText> future = new AndroidFuture<>();
try {
- mIInputContext.getSurroundingText(beforeLength, afterLength, flags, future);
+ mIInputContext.getSurroundingText(createHeader(), beforeLength, afterLength, flags,
+ future);
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -141,7 +150,8 @@
}
/**
- * Invokes {@link IInputContext#getCursorCapsMode(int, IIntResultCallback)}.
+ * Invokes
+ * {@link IInputContext#getCursorCapsMode(InputConnectionCommandHeader, int, AndroidFuture)}.
*
* @param reqModes {@code reqModes} parameter to be passed.
* @return {@link AndroidFuture<Integer>} that can be used to retrieve the invocation
@@ -152,7 +162,7 @@
public AndroidFuture<Integer> getCursorCapsMode(int reqModes) {
final AndroidFuture<Integer> future = new AndroidFuture<>();
try {
- mIInputContext.getCursorCapsMode(reqModes, future);
+ mIInputContext.getCursorCapsMode(createHeader(), reqModes, future);
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -160,8 +170,8 @@
}
/**
- * Invokes {@link IInputContext#getExtractedText(ExtractedTextRequest, int,
- * IExtractedTextResultCallback)}.
+ * Invokes {@link IInputContext#getExtractedText(InputConnectionCommandHeader,
+ * ExtractedTextRequest, int, AndroidFuture)}.
*
* @param request {@code request} parameter to be passed.
* @param flags {@code flags} parameter to be passed.
@@ -174,7 +184,7 @@
int flags) {
final AndroidFuture<ExtractedText> future = new AndroidFuture<>();
try {
- mIInputContext.getExtractedText(request, flags, future);
+ mIInputContext.getExtractedText(createHeader(), request, flags, future);
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -182,7 +192,7 @@
}
/**
- * Invokes {@link IInputContext#commitText(CharSequence, int)}.
+ * Invokes {@link IInputContext#commitText(InputConnectionCommandHeader, CharSequence, int)}.
*
* @param text {@code text} parameter to be passed.
* @param newCursorPosition {@code newCursorPosition} parameter to be passed.
@@ -192,7 +202,7 @@
@AnyThread
public boolean commitText(CharSequence text, int newCursorPosition) {
try {
- mIInputContext.commitText(text, newCursorPosition);
+ mIInputContext.commitText(createHeader(), text, newCursorPosition);
return true;
} catch (RemoteException e) {
return false;
@@ -200,7 +210,7 @@
}
/**
- * Invokes {@link IInputContext#commitCompletion(CompletionInfo)}.
+ * Invokes {@link IInputContext#commitCompletion(InputConnectionCommandHeader, CompletionInfo)}.
*
* @param text {@code text} parameter to be passed.
* @return {@code true} if the invocation is completed without {@link RemoteException}.
@@ -209,7 +219,7 @@
@AnyThread
public boolean commitCompletion(CompletionInfo text) {
try {
- mIInputContext.commitCompletion(text);
+ mIInputContext.commitCompletion(createHeader(), text);
return true;
} catch (RemoteException e) {
return false;
@@ -217,7 +227,7 @@
}
/**
- * Invokes {@link IInputContext#commitCorrection(CorrectionInfo)}.
+ * Invokes {@link IInputContext#commitCorrection(InputConnectionCommandHeader, CorrectionInfo)}.
*
* @param correctionInfo {@code correctionInfo} parameter to be passed.
* @return {@code true} if the invocation is completed without {@link RemoteException}.
@@ -226,7 +236,7 @@
@AnyThread
public boolean commitCorrection(CorrectionInfo correctionInfo) {
try {
- mIInputContext.commitCorrection(correctionInfo);
+ mIInputContext.commitCorrection(createHeader(), correctionInfo);
return true;
} catch (RemoteException e) {
return false;
@@ -234,7 +244,7 @@
}
/**
- * Invokes {@link IInputContext#setSelection(int, int)}.
+ * Invokes {@link IInputContext#setSelection(InputConnectionCommandHeader, int, int)}.
*
* @param start {@code start} parameter to be passed.
* @param end {@code start} parameter to be passed.
@@ -244,7 +254,7 @@
@AnyThread
public boolean setSelection(int start, int end) {
try {
- mIInputContext.setSelection(start, end);
+ mIInputContext.setSelection(createHeader(), start, end);
return true;
} catch (RemoteException e) {
return false;
@@ -252,7 +262,7 @@
}
/**
- * Invokes {@link IInputContext#performEditorAction(int)}.
+ * Invokes {@link IInputContext#performEditorAction(InputConnectionCommandHeader, int)}.
*
* @param actionCode {@code start} parameter to be passed.
* @return {@code true} if the invocation is completed without {@link RemoteException}.
@@ -261,7 +271,7 @@
@AnyThread
public boolean performEditorAction(int actionCode) {
try {
- mIInputContext.performEditorAction(actionCode);
+ mIInputContext.performEditorAction(createHeader(), actionCode);
return true;
} catch (RemoteException e) {
return false;
@@ -269,7 +279,7 @@
}
/**
- * Invokes {@link IInputContext#performContextMenuAction(id)}.
+ * Invokes {@link IInputContext#performContextMenuAction(InputConnectionCommandHeader, int)}.
*
* @param id {@code id} parameter to be passed.
* @return {@code true} if the invocation is completed without {@link RemoteException}.
@@ -278,7 +288,7 @@
@AnyThread
public boolean performContextMenuAction(int id) {
try {
- mIInputContext.performContextMenuAction(id);
+ mIInputContext.performContextMenuAction(createHeader(), id);
return true;
} catch (RemoteException e) {
return false;
@@ -286,7 +296,7 @@
}
/**
- * Invokes {@link IInputContext#setComposingRegion(int, int)}.
+ * Invokes {@link IInputContext#setComposingRegion(InputConnectionCommandHeader, int, int)}.
*
* @param start {@code id} parameter to be passed.
* @param end {@code id} parameter to be passed.
@@ -296,7 +306,7 @@
@AnyThread
public boolean setComposingRegion(int start, int end) {
try {
- mIInputContext.setComposingRegion(start, end);
+ mIInputContext.setComposingRegion(createHeader(), start, end);
return true;
} catch (RemoteException e) {
return false;
@@ -304,7 +314,8 @@
}
/**
- * Invokes {@link IInputContext#setComposingText(CharSequence, int)}.
+ * Invokes
+ * {@link IInputContext#setComposingText(InputConnectionCommandHeader, CharSequence, int)}.
*
* @param text {@code text} parameter to be passed.
* @param newCursorPosition {@code newCursorPosition} parameter to be passed.
@@ -314,7 +325,7 @@
@AnyThread
public boolean setComposingText(CharSequence text, int newCursorPosition) {
try {
- mIInputContext.setComposingText(text, newCursorPosition);
+ mIInputContext.setComposingText(createHeader(), text, newCursorPosition);
return true;
} catch (RemoteException e) {
return false;
@@ -322,7 +333,7 @@
}
/**
- * Invokes {@link IInputContext#finishComposingText()}.
+ * Invokes {@link IInputContext#finishComposingText(InputConnectionCommandHeader)}.
*
* @return {@code true} if the invocation is completed without {@link RemoteException}.
* {@code false} otherwise.
@@ -330,7 +341,7 @@
@AnyThread
public boolean finishComposingText() {
try {
- mIInputContext.finishComposingText();
+ mIInputContext.finishComposingText(createHeader());
return true;
} catch (RemoteException e) {
return false;
@@ -338,7 +349,7 @@
}
/**
- * Invokes {@link IInputContext#beginBatchEdit()}.
+ * Invokes {@link IInputContext#beginBatchEdit(InputConnectionCommandHeader)}.
*
* @return {@code true} if the invocation is completed without {@link RemoteException}.
* {@code false} otherwise.
@@ -346,7 +357,7 @@
@AnyThread
public boolean beginBatchEdit() {
try {
- mIInputContext.beginBatchEdit();
+ mIInputContext.beginBatchEdit(createHeader());
return true;
} catch (RemoteException e) {
return false;
@@ -354,7 +365,7 @@
}
/**
- * Invokes {@link IInputContext#endBatchEdit()}.
+ * Invokes {@link IInputContext#endBatchEdit(InputConnectionCommandHeader)}.
*
* @return {@code true} if the invocation is completed without {@link RemoteException}.
* {@code false} otherwise.
@@ -362,7 +373,7 @@
@AnyThread
public boolean endBatchEdit() {
try {
- mIInputContext.endBatchEdit();
+ mIInputContext.endBatchEdit(createHeader());
return true;
} catch (RemoteException e) {
return false;
@@ -370,7 +381,7 @@
}
/**
- * Invokes {@link IInputContext#sendKeyEvent(KeyEvent)}.
+ * Invokes {@link IInputContext#sendKeyEvent(InputConnectionCommandHeader, KeyEvent)}.
*
* @param event {@code event} parameter to be passed.
* @return {@code true} if the invocation is completed without {@link RemoteException}.
@@ -379,7 +390,7 @@
@AnyThread
public boolean sendKeyEvent(KeyEvent event) {
try {
- mIInputContext.sendKeyEvent(event);
+ mIInputContext.sendKeyEvent(createHeader(), event);
return true;
} catch (RemoteException e) {
return false;
@@ -387,7 +398,7 @@
}
/**
- * Invokes {@link IInputContext#clearMetaKeyStates(int)}.
+ * Invokes {@link IInputContext#clearMetaKeyStates(InputConnectionCommandHeader, int)}.
*
* @param states {@code states} parameter to be passed.
* @return {@code true} if the invocation is completed without {@link RemoteException}.
@@ -396,7 +407,7 @@
@AnyThread
public boolean clearMetaKeyStates(int states) {
try {
- mIInputContext.clearMetaKeyStates(states);
+ mIInputContext.clearMetaKeyStates(createHeader(), states);
return true;
} catch (RemoteException e) {
return false;
@@ -404,7 +415,7 @@
}
/**
- * Invokes {@link IInputContext#deleteSurroundingText(int, int)}.
+ * Invokes {@link IInputContext#deleteSurroundingText(InputConnectionCommandHeader, int, int)}.
*
* @param beforeLength {@code beforeLength} parameter to be passed.
* @param afterLength {@code afterLength} parameter to be passed.
@@ -414,7 +425,7 @@
@AnyThread
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
try {
- mIInputContext.deleteSurroundingText(beforeLength, afterLength);
+ mIInputContext.deleteSurroundingText(createHeader(), beforeLength, afterLength);
return true;
} catch (RemoteException e) {
return false;
@@ -422,7 +433,8 @@
}
/**
- * Invokes {@link IInputContext#deleteSurroundingTextInCodePoints(int, int)}.
+ * Invokes {@link IInputContext#deleteSurroundingTextInCodePoints(InputConnectionCommandHeader,
+ * int, int)}.
*
* @param beforeLength {@code beforeLength} parameter to be passed.
* @param afterLength {@code afterLength} parameter to be passed.
@@ -432,7 +444,8 @@
@AnyThread
public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
try {
- mIInputContext.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
+ mIInputContext.deleteSurroundingTextInCodePoints(createHeader(), beforeLength,
+ afterLength);
return true;
} catch (RemoteException e) {
return false;
@@ -440,7 +453,7 @@
}
/**
- * Invokes {@link IInputContext#performSpellCheck()}.
+ * Invokes {@link IInputContext#performSpellCheck(InputConnectionCommandHeader)}.
*
* @return {@code true} if the invocation is completed without {@link RemoteException}.
* {@code false} otherwise.
@@ -448,7 +461,7 @@
@AnyThread
public boolean performSpellCheck() {
try {
- mIInputContext.performSpellCheck();
+ mIInputContext.performSpellCheck(createHeader());
return true;
} catch (RemoteException e) {
return false;
@@ -456,7 +469,8 @@
}
/**
- * Invokes {@link IInputContext#performPrivateCommand(String, Bundle)}.
+ * Invokes
+ * {@link IInputContext#performPrivateCommand(InputConnectionCommandHeader, String, Bundle)}.
*
* @param action {@code action} parameter to be passed.
* @param data {@code data} parameter to be passed.
@@ -466,7 +480,7 @@
@AnyThread
public boolean performPrivateCommand(String action, Bundle data) {
try {
- mIInputContext.performPrivateCommand(action, data);
+ mIInputContext.performPrivateCommand(createHeader(), action, data);
return true;
} catch (RemoteException e) {
return false;
@@ -474,7 +488,8 @@
}
/**
- * Invokes {@link IInputContext#requestCursorUpdates(int, IIntResultCallback)}.
+ * Invokes {@link IInputContext#requestCursorUpdates(InputConnectionCommandHeader, int, int,
+ * AndroidFuture)}.
*
* @param cursorUpdateMode {@code cursorUpdateMode} parameter to be passed.
* @param imeDisplayId the display ID that is associated with the IME.
@@ -486,7 +501,8 @@
public AndroidFuture<Boolean> requestCursorUpdates(int cursorUpdateMode, int imeDisplayId) {
final AndroidFuture<Boolean> future = new AndroidFuture<>();
try {
- mIInputContext.requestCursorUpdates(cursorUpdateMode, imeDisplayId, future);
+ mIInputContext.requestCursorUpdates(createHeader(), cursorUpdateMode, imeDisplayId,
+ future);
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -494,8 +510,8 @@
}
/**
- * Invokes
- * {@link IInputContext#commitContent(InputContentInfo, int, Bundle, IIntResultCallback)}.
+ * Invokes {@link IInputContext#commitContent(InputConnectionCommandHeader, InputContentInfo,
+ * int, Bundle, AndroidFuture)}.
*
* @param inputContentInfo {@code inputContentInfo} parameter to be passed.
* @param flags {@code flags} parameter to be passed.
@@ -509,7 +525,7 @@
Bundle opts) {
final AndroidFuture<Boolean> future = new AndroidFuture<>();
try {
- mIInputContext.commitContent(inputContentInfo, flags, opts, future);
+ mIInputContext.commitContent(createHeader(), inputContentInfo, flags, opts, future);
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -517,7 +533,7 @@
}
/**
- * Invokes {@link IInputContext#setImeConsumesInput(boolean)}.
+ * Invokes {@link IInputContext#setImeConsumesInput(InputConnectionCommandHeader, boolean)}.
*
* @param imeConsumesInput {@code imeConsumesInput} parameter to be passed.
* @return {@code true} if the invocation is completed without {@link RemoteException}.
@@ -526,7 +542,7 @@
@AnyThread
public boolean setImeConsumesInput(boolean imeConsumesInput) {
try {
- mIInputContext.setImeConsumesInput(imeConsumesInput);
+ mIInputContext.setImeConsumesInput(createHeader(), imeConsumesInput);
return true;
} catch (RemoteException e) {
return false;
diff --git a/core/java/com/android/internal/inputmethod/InputConnectionCommandHeader.aidl b/core/java/com/android/internal/inputmethod/InputConnectionCommandHeader.aidl
new file mode 100644
index 0000000..9de3ffc
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputConnectionCommandHeader.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.internal.inputmethod;
+
+parcelable InputConnectionCommandHeader;
\ No newline at end of file
diff --git a/core/java/com/android/internal/inputmethod/InputConnectionCommandHeader.java b/core/java/com/android/internal/inputmethod/InputConnectionCommandHeader.java
new file mode 100644
index 0000000..4bd8d0c
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputConnectionCommandHeader.java
@@ -0,0 +1,53 @@
+/*
+ * 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.internal.inputmethod;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A common IPC header used behind {@link RemoteInputConnectionImpl} and
+ * {@link android.inputmethodservice.RemoteInputConnection}.
+ */
+public final class InputConnectionCommandHeader implements Parcelable {
+ public InputConnectionCommandHeader() {
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @NonNull
+ public static final Parcelable.Creator<InputConnectionCommandHeader> CREATOR =
+ new Parcelable.Creator<InputConnectionCommandHeader>() {
+ @NonNull
+ public InputConnectionCommandHeader createFromParcel(Parcel in) {
+ return new InputConnectionCommandHeader();
+ }
+
+ @NonNull
+ public InputConnectionCommandHeader[] newArray(int size) {
+ return new InputConnectionCommandHeader[size];
+ }
+ };
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ }
+}
diff --git a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java
index 7a668fb..3867afd 100644
--- a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java
+++ b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java
@@ -225,7 +225,7 @@
}
@Override
- public void getTextAfterCursor(int length, int flags,
+ public void getTextAfterCursor(InputConnectionCommandHeader header, int length, int flags,
AndroidFuture future /* T=CharSequence */) {
dispatchWithTracing("getTextAfterCursor", future, () -> {
final InputConnection ic = getInputConnection();
@@ -243,7 +243,7 @@
}
@Override
- public void getTextBeforeCursor(int length, int flags,
+ public void getTextBeforeCursor(InputConnectionCommandHeader header, int length, int flags,
AndroidFuture future /* T=CharSequence */) {
dispatchWithTracing("getTextBeforeCursor", future, () -> {
final InputConnection ic = getInputConnection();
@@ -261,7 +261,8 @@
}
@Override
- public void getSelectedText(int flags, AndroidFuture future /* T=CharSequence */) {
+ public void getSelectedText(InputConnectionCommandHeader header, int flags,
+ AndroidFuture future /* T=CharSequence */) {
dispatchWithTracing("getSelectedText", future, () -> {
final InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -278,8 +279,8 @@
}
@Override
- public void getSurroundingText(int beforeLength, int afterLength, int flags,
- AndroidFuture future /* T=SurroundingText */) {
+ public void getSurroundingText(InputConnectionCommandHeader header, int beforeLength,
+ int afterLength, int flags, AndroidFuture future /* T=SurroundingText */) {
dispatchWithTracing("getSurroundingText", future, () -> {
final InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -302,7 +303,8 @@
}
@Override
- public void getCursorCapsMode(int reqModes, AndroidFuture future /* T=Integer */) {
+ public void getCursorCapsMode(InputConnectionCommandHeader header, int reqModes,
+ AndroidFuture future /* T=Integer */) {
dispatchWithTracing("getCursorCapsMode", future, () -> {
final InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -314,8 +316,8 @@
}
@Override
- public void getExtractedText(ExtractedTextRequest request, int flags,
- AndroidFuture future /* T=ExtractedText */) {
+ public void getExtractedText(InputConnectionCommandHeader header, ExtractedTextRequest request,
+ int flags, AndroidFuture future /* T=ExtractedText */) {
dispatchWithTracing("getExtractedText", future, () -> {
final InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -327,7 +329,8 @@
}
@Override
- public void commitText(CharSequence text, int newCursorPosition) {
+ public void commitText(InputConnectionCommandHeader header, CharSequence text,
+ int newCursorPosition) {
dispatchWithTracing("commitText", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -339,7 +342,7 @@
}
@Override
- public void commitCompletion(CompletionInfo text) {
+ public void commitCompletion(InputConnectionCommandHeader header, CompletionInfo text) {
dispatchWithTracing("commitCompletion", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -351,7 +354,7 @@
}
@Override
- public void commitCorrection(CorrectionInfo info) {
+ public void commitCorrection(InputConnectionCommandHeader header, CorrectionInfo info) {
dispatchWithTracing("commitCorrection", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -367,7 +370,7 @@
}
@Override
- public void setSelection(int start, int end) {
+ public void setSelection(InputConnectionCommandHeader header, int start, int end) {
dispatchWithTracing("setSelection", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -379,7 +382,7 @@
}
@Override
- public void performEditorAction(int id) {
+ public void performEditorAction(InputConnectionCommandHeader header, int id) {
dispatchWithTracing("performEditorAction", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -391,7 +394,7 @@
}
@Override
- public void performContextMenuAction(int id) {
+ public void performContextMenuAction(InputConnectionCommandHeader header, int id) {
dispatchWithTracing("performContextMenuAction", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -403,7 +406,7 @@
}
@Override
- public void setComposingRegion(int start, int end) {
+ public void setComposingRegion(InputConnectionCommandHeader header, int start, int end) {
dispatchWithTracing("setComposingRegion", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -419,7 +422,8 @@
}
@Override
- public void setComposingText(CharSequence text, int newCursorPosition) {
+ public void setComposingText(InputConnectionCommandHeader header, CharSequence text,
+ int newCursorPosition) {
dispatchWithTracing("setComposingText", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -430,8 +434,36 @@
});
}
+ /**
+ * Dispatches {@link InputConnection#finishComposingText()}.
+ *
+ * <p>This method is intended to be called only from {@link InputMethodManager}.</p>
+ */
+ public void finishComposingTextFromImm() {
+ dispatchWithTracing("finishComposingTextFromImm", () -> {
+ if (isFinished()) {
+ // In this case, #finishComposingText() is guaranteed to be called already.
+ // There should be no negative impact if we ignore this call silently.
+ if (DEBUG) {
+ Log.w(TAG, "Bug 35301295: Redundant finishComposingTextFromImm.");
+ }
+ return;
+ }
+ InputConnection ic = getInputConnection();
+ // Note we do NOT check isActive() here, because this is safe
+ // for an IME to call at any time, and we need to allow it
+ // through to clean up our state after the IME has switched to
+ // another client.
+ if (ic == null) {
+ Log.w(TAG, "finishComposingTextFromImm on inactive InputConnection");
+ return;
+ }
+ ic.finishComposingText();
+ });
+ }
+
@Override
- public void finishComposingText() {
+ public void finishComposingText(InputConnectionCommandHeader header) {
dispatchWithTracing("finishComposingText", () -> {
if (isFinished()) {
// In this case, #finishComposingText() is guaranteed to be called already.
@@ -455,7 +487,7 @@
}
@Override
- public void sendKeyEvent(KeyEvent event) {
+ public void sendKeyEvent(InputConnectionCommandHeader header, KeyEvent event) {
dispatchWithTracing("sendKeyEvent", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -467,7 +499,7 @@
}
@Override
- public void clearMetaKeyStates(int states) {
+ public void clearMetaKeyStates(InputConnectionCommandHeader header, int states) {
dispatchWithTracing("clearMetaKeyStates", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -479,7 +511,8 @@
}
@Override
- public void deleteSurroundingText(int beforeLength, int afterLength) {
+ public void deleteSurroundingText(InputConnectionCommandHeader header, int beforeLength,
+ int afterLength) {
dispatchWithTracing("deleteSurroundingText", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -491,7 +524,8 @@
}
@Override
- public void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
+ public void deleteSurroundingTextInCodePoints(InputConnectionCommandHeader header,
+ int beforeLength, int afterLength) {
dispatchWithTracing("deleteSurroundingTextInCodePoints", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -507,7 +541,7 @@
}
@Override
- public void beginBatchEdit() {
+ public void beginBatchEdit(InputConnectionCommandHeader header) {
dispatchWithTracing("beginBatchEdit", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -519,7 +553,7 @@
}
@Override
- public void endBatchEdit() {
+ public void endBatchEdit(InputConnectionCommandHeader header) {
dispatchWithTracing("endBatchEdit", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -531,7 +565,7 @@
}
@Override
- public void performSpellCheck() {
+ public void performSpellCheck(InputConnectionCommandHeader header) {
dispatchWithTracing("performSpellCheck", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -543,7 +577,8 @@
}
@Override
- public void performPrivateCommand(String action, Bundle data) {
+ public void performPrivateCommand(InputConnectionCommandHeader header, String action,
+ Bundle data) {
dispatchWithTracing("performPrivateCommand", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -555,8 +590,8 @@
}
@Override
- public void requestCursorUpdates(int cursorUpdateMode, int imeDisplayId,
- AndroidFuture future /* T=Boolean */) {
+ public void requestCursorUpdates(InputConnectionCommandHeader header, int cursorUpdateMode,
+ int imeDisplayId, AndroidFuture future /* T=Boolean */) {
dispatchWithTracing("requestCursorUpdates", future, () -> {
final InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
@@ -577,7 +612,8 @@
}
@Override
- public void commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts,
+ public void commitContent(InputConnectionCommandHeader header,
+ InputContentInfo inputContentInfo, int flags, Bundle opts,
AndroidFuture future /* T=Boolean */) {
dispatchWithTracing("commitContent", future, () -> {
final InputConnection ic = getInputConnection();
@@ -599,7 +635,7 @@
}
@Override
- public void setImeConsumesInput(boolean imeConsumesInput) {
+ public void setImeConsumesInput(InputConnectionCommandHeader header, boolean imeConsumesInput) {
dispatchWithTracing("setImeConsumesInput", () -> {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
diff --git a/core/java/com/android/internal/view/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl
index 2e6f9e5..df55beb 100644
--- a/core/java/com/android/internal/view/IInputContext.aidl
+++ b/core/java/com/android/internal/view/IInputContext.aidl
@@ -24,6 +24,7 @@
import android.view.inputmethod.InputContentInfo;
import com.android.internal.infra.AndroidFuture;
+import com.android.internal.inputmethod.InputConnectionCommandHeader;
/**
* Interface from an input method to the application, allowing it to perform
@@ -31,58 +32,67 @@
* {@hide}
*/
oneway interface IInputContext {
- void getTextBeforeCursor(int length, int flags, in AndroidFuture future /* T=CharSequence */);
+ void getTextBeforeCursor(in InputConnectionCommandHeader header, int length, int flags,
+ in AndroidFuture future /* T=CharSequence */);
- void getTextAfterCursor(int length, int flags, in AndroidFuture future /* T=CharSequence */);
+ void getTextAfterCursor(in InputConnectionCommandHeader header, int length, int flags,
+ in AndroidFuture future /* T=CharSequence */);
- void getCursorCapsMode(int reqModes, in AndroidFuture future /* T=Integer */);
+ void getCursorCapsMode(in InputConnectionCommandHeader header, int reqModes,
+ in AndroidFuture future /* T=Integer */);
- void getExtractedText(in ExtractedTextRequest request, int flags,
- in AndroidFuture future /* T=ExtractedText */);
+ void getExtractedText(in InputConnectionCommandHeader header, in ExtractedTextRequest request,
+ int flags, in AndroidFuture future /* T=ExtractedText */);
- void deleteSurroundingText(int beforeLength, int afterLength);
- void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength);
+ void deleteSurroundingText(in InputConnectionCommandHeader header, int beforeLength,
+ int afterLength);
+ void deleteSurroundingTextInCodePoints(in InputConnectionCommandHeader header, int beforeLength,
+ int afterLength);
- void setComposingText(CharSequence text, int newCursorPosition);
+ void setComposingText(in InputConnectionCommandHeader header, CharSequence text,
+ int newCursorPosition);
- void finishComposingText();
+ void finishComposingText(in InputConnectionCommandHeader header);
- void commitText(CharSequence text, int newCursorPosition);
+ void commitText(in InputConnectionCommandHeader header, CharSequence text,
+ int newCursorPosition);
- void commitCompletion(in CompletionInfo completion);
+ void commitCompletion(in InputConnectionCommandHeader header, in CompletionInfo completion);
- void commitCorrection(in CorrectionInfo correction);
+ void commitCorrection(in InputConnectionCommandHeader header, in CorrectionInfo correction);
- void setSelection(int start, int end);
+ void setSelection(in InputConnectionCommandHeader header, int start, int end);
- void performEditorAction(int actionCode);
+ void performEditorAction(in InputConnectionCommandHeader header, int actionCode);
- void performContextMenuAction(int id);
+ void performContextMenuAction(in InputConnectionCommandHeader header, int id);
- void beginBatchEdit();
+ void beginBatchEdit(in InputConnectionCommandHeader header);
- void endBatchEdit();
+ void endBatchEdit(in InputConnectionCommandHeader header);
- void sendKeyEvent(in KeyEvent event);
+ void sendKeyEvent(in InputConnectionCommandHeader header, in KeyEvent event);
- void clearMetaKeyStates(int states);
+ void clearMetaKeyStates(in InputConnectionCommandHeader header, int states);
- void performSpellCheck();
+ void performSpellCheck(in InputConnectionCommandHeader header);
- void performPrivateCommand(String action, in Bundle data);
+ void performPrivateCommand(in InputConnectionCommandHeader header, String action,
+ in Bundle data);
- void setComposingRegion(int start, int end);
+ void setComposingRegion(in InputConnectionCommandHeader header, int start, int end);
- void getSelectedText(int flags, in AndroidFuture future /* T=CharSequence */);
+ void getSelectedText(in InputConnectionCommandHeader header, int flags,
+ in AndroidFuture future /* T=CharSequence */);
- void requestCursorUpdates(int cursorUpdateMode, int imeDisplayId,
- in AndroidFuture future /* T=Boolean */);
+ void requestCursorUpdates(in InputConnectionCommandHeader header, int cursorUpdateMode,
+ int imeDisplayId, in AndroidFuture future /* T=Boolean */);
- void commitContent(in InputContentInfo inputContentInfo, int flags, in Bundle opts,
- in AndroidFuture future /* T=Boolean */);
+ void commitContent(in InputConnectionCommandHeader header, in InputContentInfo inputContentInfo,
+ int flags, in Bundle opts, in AndroidFuture future /* T=Boolean */);
- void getSurroundingText(int beforeLength, int afterLength, int flags,
- in AndroidFuture future /* T=SurroundingText */);
+ void getSurroundingText(in InputConnectionCommandHeader header, int beforeLength,
+ int afterLength, int flags, in AndroidFuture future /* T=SurroundingText */);
- void setImeConsumesInput(boolean imeConsumesInput);
+ void setImeConsumesInput(in InputConnectionCommandHeader header, boolean imeConsumesInput);
}
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 514e0b8..a0bf9b5 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -16,62 +16,18 @@
package com.android.internal.widget;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.Region;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.util.Size;
-import android.view.ContextThemeWrapper;
-import android.view.Gravity;
-import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.MotionEvent;
import android.view.View;
-import android.view.View.MeasureSpec;
import android.view.View.OnLayoutChangeListener;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.view.Window;
-import android.view.WindowManager;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.Transformation;
-import android.widget.ArrayAdapter;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ListView;
import android.widget.PopupWindow;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Comparator;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
/**
@@ -90,7 +46,6 @@
private static final MenuItem.OnMenuItemClickListener NO_OP_MENUITEM_CLICK_LISTENER =
item -> false;
- private final Context mContext;
private final Window mWindow;
private final FloatingToolbarPopup mPopup;
@@ -158,9 +113,8 @@
public FloatingToolbar(Window window) {
// TODO(b/65172902): Pass context in constructor when DecorView (and other callers)
// supports multi-display.
- mContext = applyDefaultTheme(window.getContext());
mWindow = Objects.requireNonNull(window);
- mPopup = new FloatingToolbarPopup(mContext, window.getDecorView());
+ mPopup = new FloatingToolbarPopup(window.getContext(), window.getDecorView());
}
/**
@@ -321,1544 +275,4 @@
private void unregisterOrientationHandler() {
mWindow.getDecorView().removeOnLayoutChangeListener(mOrientationChangeHandler);
}
-
-
- /**
- * A popup window used by the floating toolbar.
- *
- * This class is responsible for the rendering/animation of the floating toolbar.
- * It holds 2 panels (i.e. main panel and overflow panel) and an overflow button
- * to transition between panels.
- */
- private static final class FloatingToolbarPopup {
-
- /* Minimum and maximum number of items allowed in the overflow. */
- private static final int MIN_OVERFLOW_SIZE = 2;
- private static final int MAX_OVERFLOW_SIZE = 4;
-
- private final Context mContext;
- private final View mParent; // Parent for the popup window.
- private final PopupWindow mPopupWindow;
-
- /* Margins between the popup window and it's content. */
- private final int mMarginHorizontal;
- private final int mMarginVertical;
-
- /* View components */
- private final ViewGroup mContentContainer; // holds all contents.
- private final ViewGroup mMainPanel; // holds menu items that are initially displayed.
- private final OverflowPanel mOverflowPanel; // holds menu items hidden in the overflow.
- private final ImageButton mOverflowButton; // opens/closes the overflow.
- /* overflow button drawables. */
- private final Drawable mArrow;
- private final Drawable mOverflow;
- private final AnimatedVectorDrawable mToArrow;
- private final AnimatedVectorDrawable mToOverflow;
-
- private final OverflowPanelViewHelper mOverflowPanelViewHelper;
-
- /* Animation interpolators. */
- private final Interpolator mLogAccelerateInterpolator;
- private final Interpolator mFastOutSlowInInterpolator;
- private final Interpolator mLinearOutSlowInInterpolator;
- private final Interpolator mFastOutLinearInInterpolator;
-
- /* Animations. */
- private final AnimatorSet mShowAnimation;
- private final AnimatorSet mDismissAnimation;
- private final AnimatorSet mHideAnimation;
- private final AnimationSet mOpenOverflowAnimation;
- private final AnimationSet mCloseOverflowAnimation;
- private final Animation.AnimationListener mOverflowAnimationListener;
-
- private final Rect mViewPortOnScreen = new Rect(); // portion of screen we can draw in.
- private final Point mCoordsOnWindow = new Point(); // popup window coordinates.
- /* Temporary data holders. Reset values before using. */
- private final int[] mTmpCoords = new int[2];
-
- private final Region mTouchableRegion = new Region();
- private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer =
- info -> {
- info.contentInsets.setEmpty();
- info.visibleInsets.setEmpty();
- info.touchableRegion.set(mTouchableRegion);
- info.setTouchableInsets(
- ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
- };
-
- private final int mLineHeight;
- private final int mIconTextSpacing;
-
- /**
- * @see OverflowPanelViewHelper#preparePopupContent().
- */
- private final Runnable mPreparePopupContentRTLHelper = new Runnable() {
- @Override
- public void run() {
- setPanelsStatesAtRestingPosition();
- setContentAreaAsTouchableSurface();
- mContentContainer.setAlpha(1);
- }
- };
-
- private boolean mDismissed = true; // tracks whether this popup is dismissed or dismissing.
- private boolean mHidden; // tracks whether this popup is hidden or hiding.
-
- /* Calculated sizes for panels and overflow button. */
- private final Size mOverflowButtonSize;
- private Size mOverflowPanelSize; // Should be null when there is no overflow.
- private Size mMainPanelSize;
-
- /* Menu items and click listeners */
- private final Map<MenuItemRepr, MenuItem> mMenuItems = new LinkedHashMap<>();
- private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener;
- private final View.OnClickListener mMenuItemButtonOnClickListener =
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mOnMenuItemClickListener == null) {
- return;
- }
- final Object tag = v.getTag();
- if (!(tag instanceof MenuItemRepr)) {
- return;
- }
- final MenuItem menuItem = mMenuItems.get((MenuItemRepr) tag);
- if (menuItem == null) {
- return;
- }
- mOnMenuItemClickListener.onMenuItemClick(menuItem);
- }
- };
-
- private boolean mOpenOverflowUpwards; // Whether the overflow opens upwards or downwards.
- private boolean mIsOverflowOpen;
-
- private int mTransitionDurationScale; // Used to scale the toolbar transition duration.
-
- /**
- * Initializes a new floating toolbar popup.
- *
- * @param parent A parent view to get the {@link android.view.View#getWindowToken()} token
- * from.
- */
- public FloatingToolbarPopup(Context context, View parent) {
- mParent = Objects.requireNonNull(parent);
- mContext = Objects.requireNonNull(context);
- mContentContainer = createContentContainer(context);
- mPopupWindow = createPopupWindow(mContentContainer);
- mMarginHorizontal = parent.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
- mMarginVertical = parent.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_vertical_margin);
- mLineHeight = context.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_height);
- mIconTextSpacing = context.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_icon_text_spacing);
-
- // Interpolators
- mLogAccelerateInterpolator = new LogAccelerateInterpolator();
- mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
- mContext, android.R.interpolator.fast_out_slow_in);
- mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(
- mContext, android.R.interpolator.linear_out_slow_in);
- mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(
- mContext, android.R.interpolator.fast_out_linear_in);
-
- // Drawables. Needed for views.
- mArrow = mContext.getResources()
- .getDrawable(R.drawable.ft_avd_tooverflow, mContext.getTheme());
- mArrow.setAutoMirrored(true);
- mOverflow = mContext.getResources()
- .getDrawable(R.drawable.ft_avd_toarrow, mContext.getTheme());
- mOverflow.setAutoMirrored(true);
- mToArrow = (AnimatedVectorDrawable) mContext.getResources()
- .getDrawable(R.drawable.ft_avd_toarrow_animation, mContext.getTheme());
- mToArrow.setAutoMirrored(true);
- mToOverflow = (AnimatedVectorDrawable) mContext.getResources()
- .getDrawable(R.drawable.ft_avd_tooverflow_animation, mContext.getTheme());
- mToOverflow.setAutoMirrored(true);
-
- // Views
- mOverflowButton = createOverflowButton();
- mOverflowButtonSize = measure(mOverflowButton);
- mMainPanel = createMainPanel();
- mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext, mIconTextSpacing);
- mOverflowPanel = createOverflowPanel();
-
- // Animation. Need views.
- mOverflowAnimationListener = createOverflowAnimationListener();
- mOpenOverflowAnimation = new AnimationSet(true);
- mOpenOverflowAnimation.setAnimationListener(mOverflowAnimationListener);
- mCloseOverflowAnimation = new AnimationSet(true);
- mCloseOverflowAnimation.setAnimationListener(mOverflowAnimationListener);
- mShowAnimation = createEnterAnimation(mContentContainer);
- mDismissAnimation = createExitAnimation(
- mContentContainer,
- 150, // startDelay
- new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mPopupWindow.dismiss();
- mContentContainer.removeAllViews();
- }
- });
- mHideAnimation = createExitAnimation(
- mContentContainer,
- 0, // startDelay
- new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mPopupWindow.dismiss();
- }
- });
- }
-
- /**
- * Makes this toolbar "outside touchable" and sets the onDismissListener.
- *
- * @param outsideTouchable if true, the popup will be made "outside touchable" and
- * "non focusable". The reverse will happen if false.
- * @param onDismiss
- *
- * @return true if the "outsideTouchable" setting was modified. Otherwise returns false
- *
- * @see PopupWindow#setOutsideTouchable(boolean)
- * @see PopupWindow#setFocusable(boolean)
- * @see PopupWindow.OnDismissListener
- */
- public boolean setOutsideTouchable(
- boolean outsideTouchable, @Nullable PopupWindow.OnDismissListener onDismiss) {
- boolean ret = false;
- if (mPopupWindow.isOutsideTouchable() ^ outsideTouchable) {
- mPopupWindow.setOutsideTouchable(outsideTouchable);
- mPopupWindow.setFocusable(!outsideTouchable);
- mPopupWindow.update();
- ret = true;
- }
- mPopupWindow.setOnDismissListener(onDismiss);
- return ret;
- }
-
- /**
- * Lays out buttons for the specified menu items.
- * Requires a subsequent call to {@link #show()} to show the items.
- */
- public void layoutMenuItems(
- List<MenuItem> menuItems,
- MenuItem.OnMenuItemClickListener menuItemClickListener,
- int suggestedWidth) {
- cancelOverflowAnimations();
- clearPanels();
- updateMenuItems(menuItems, menuItemClickListener);
- menuItems = layoutMainPanelItems(menuItems, getAdjustedToolbarWidth(suggestedWidth));
- if (!menuItems.isEmpty()) {
- // Add remaining items to the overflow.
- layoutOverflowPanelItems(menuItems);
- }
- updatePopupSize();
- }
-
- /**
- * Updates the popup's menu items without rebuilding the widget.
- * Use in place of layoutMenuItems() when the popup's views need not be reconstructed.
- *
- * @see isLayoutRequired(List<MenuItem>)
- */
- public void updateMenuItems(
- List<MenuItem> menuItems, MenuItem.OnMenuItemClickListener menuItemClickListener) {
- mMenuItems.clear();
- for (MenuItem menuItem : menuItems) {
- mMenuItems.put(MenuItemRepr.of(menuItem), menuItem);
- }
- mOnMenuItemClickListener = menuItemClickListener;
- }
-
- /**
- * Returns true if this popup needs a relayout to properly render the specified menu items.
- */
- public boolean isLayoutRequired(List<MenuItem> menuItems) {
- return !MenuItemRepr.reprEquals(menuItems, mMenuItems.values());
- }
-
- /**
- * Shows this popup at the specified coordinates.
- * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
- */
- public void show(Rect contentRectOnScreen) {
- Objects.requireNonNull(contentRectOnScreen);
-
- if (isShowing()) {
- return;
- }
-
- mHidden = false;
- mDismissed = false;
- cancelDismissAndHideAnimations();
- cancelOverflowAnimations();
-
- refreshCoordinatesAndOverflowDirection(contentRectOnScreen);
- preparePopupContent();
- // We need to specify the position in window coordinates.
- // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can
- // specify the popup position in screen coordinates.
- mPopupWindow.showAtLocation(
- mParent, Gravity.NO_GRAVITY, mCoordsOnWindow.x, mCoordsOnWindow.y);
- setTouchableSurfaceInsetsComputer();
- runShowAnimation();
- }
-
- /**
- * Gets rid of this popup. If the popup isn't currently showing, this will be a no-op.
- */
- public void dismiss() {
- if (mDismissed) {
- return;
- }
-
- mHidden = false;
- mDismissed = true;
- mHideAnimation.cancel();
-
- runDismissAnimation();
- setZeroTouchableSurface();
- }
-
- /**
- * Hides this popup. This is a no-op if this popup is not showing.
- * Use {@link #isHidden()} to distinguish between a hidden and a dismissed popup.
- */
- public void hide() {
- if (!isShowing()) {
- return;
- }
-
- mHidden = true;
- runHideAnimation();
- setZeroTouchableSurface();
- }
-
- /**
- * Returns {@code true} if this popup is currently showing. {@code false} otherwise.
- */
- public boolean isShowing() {
- return !mDismissed && !mHidden;
- }
-
- /**
- * Returns {@code true} if this popup is currently hidden. {@code false} otherwise.
- */
- public boolean isHidden() {
- return mHidden;
- }
-
- /**
- * Updates the coordinates of this popup.
- * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
- * This is a no-op if this popup is not showing.
- */
- public void updateCoordinates(Rect contentRectOnScreen) {
- Objects.requireNonNull(contentRectOnScreen);
-
- if (!isShowing() || !mPopupWindow.isShowing()) {
- return;
- }
-
- cancelOverflowAnimations();
- refreshCoordinatesAndOverflowDirection(contentRectOnScreen);
- preparePopupContent();
- // We need to specify the position in window coordinates.
- // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can
- // specify the popup position in screen coordinates.
- mPopupWindow.update(
- mCoordsOnWindow.x, mCoordsOnWindow.y,
- mPopupWindow.getWidth(), mPopupWindow.getHeight());
- }
-
- private void refreshCoordinatesAndOverflowDirection(Rect contentRectOnScreen) {
- refreshViewPort();
-
- // Initialize x ensuring that the toolbar isn't rendered behind the nav bar in
- // landscape.
- final int x = Math.min(
- contentRectOnScreen.centerX() - mPopupWindow.getWidth() / 2,
- mViewPortOnScreen.right - mPopupWindow.getWidth());
-
- final int y;
-
- final int availableHeightAboveContent =
- contentRectOnScreen.top - mViewPortOnScreen.top;
- final int availableHeightBelowContent =
- mViewPortOnScreen.bottom - contentRectOnScreen.bottom;
-
- final int margin = 2 * mMarginVertical;
- final int toolbarHeightWithVerticalMargin = mLineHeight + margin;
-
- if (!hasOverflow()) {
- if (availableHeightAboveContent >= toolbarHeightWithVerticalMargin) {
- // There is enough space at the top of the content.
- y = contentRectOnScreen.top - toolbarHeightWithVerticalMargin;
- } else if (availableHeightBelowContent >= toolbarHeightWithVerticalMargin) {
- // There is enough space at the bottom of the content.
- y = contentRectOnScreen.bottom;
- } else if (availableHeightBelowContent >= mLineHeight) {
- // Just enough space to fit the toolbar with no vertical margins.
- y = contentRectOnScreen.bottom - mMarginVertical;
- } else {
- // Not enough space. Prefer to position as high as possible.
- y = Math.max(
- mViewPortOnScreen.top,
- contentRectOnScreen.top - toolbarHeightWithVerticalMargin);
- }
- } else {
- // Has an overflow.
- final int minimumOverflowHeightWithMargin =
- calculateOverflowHeight(MIN_OVERFLOW_SIZE) + margin;
- final int availableHeightThroughContentDown = mViewPortOnScreen.bottom -
- contentRectOnScreen.top + toolbarHeightWithVerticalMargin;
- final int availableHeightThroughContentUp = contentRectOnScreen.bottom -
- mViewPortOnScreen.top + toolbarHeightWithVerticalMargin;
-
- if (availableHeightAboveContent >= minimumOverflowHeightWithMargin) {
- // There is enough space at the top of the content rect for the overflow.
- // Position above and open upwards.
- updateOverflowHeight(availableHeightAboveContent - margin);
- y = contentRectOnScreen.top - mPopupWindow.getHeight();
- mOpenOverflowUpwards = true;
- } else if (availableHeightAboveContent >= toolbarHeightWithVerticalMargin
- && availableHeightThroughContentDown >= minimumOverflowHeightWithMargin) {
- // There is enough space at the top of the content rect for the main panel
- // but not the overflow.
- // Position above but open downwards.
- updateOverflowHeight(availableHeightThroughContentDown - margin);
- y = contentRectOnScreen.top - toolbarHeightWithVerticalMargin;
- mOpenOverflowUpwards = false;
- } else if (availableHeightBelowContent >= minimumOverflowHeightWithMargin) {
- // There is enough space at the bottom of the content rect for the overflow.
- // Position below and open downwards.
- updateOverflowHeight(availableHeightBelowContent - margin);
- y = contentRectOnScreen.bottom;
- mOpenOverflowUpwards = false;
- } else if (availableHeightBelowContent >= toolbarHeightWithVerticalMargin
- && mViewPortOnScreen.height() >= minimumOverflowHeightWithMargin) {
- // There is enough space at the bottom of the content rect for the main panel
- // but not the overflow.
- // Position below but open upwards.
- updateOverflowHeight(availableHeightThroughContentUp - margin);
- y = contentRectOnScreen.bottom + toolbarHeightWithVerticalMargin -
- mPopupWindow.getHeight();
- mOpenOverflowUpwards = true;
- } else {
- // Not enough space.
- // Position at the top of the view port and open downwards.
- updateOverflowHeight(mViewPortOnScreen.height() - margin);
- y = mViewPortOnScreen.top;
- mOpenOverflowUpwards = false;
- }
- }
-
- // We later specify the location of PopupWindow relative to the attached window.
- // The idea here is that 1) we can get the location of a View in both window coordinates
- // and screen coordiantes, where the offset between them should be equal to the window
- // origin, and 2) we can use an arbitrary for this calculation while calculating the
- // location of the rootview is supposed to be least expensive.
- // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can avoid
- // the following calculation.
- mParent.getRootView().getLocationOnScreen(mTmpCoords);
- int rootViewLeftOnScreen = mTmpCoords[0];
- int rootViewTopOnScreen = mTmpCoords[1];
- mParent.getRootView().getLocationInWindow(mTmpCoords);
- int rootViewLeftOnWindow = mTmpCoords[0];
- int rootViewTopOnWindow = mTmpCoords[1];
- int windowLeftOnScreen = rootViewLeftOnScreen - rootViewLeftOnWindow;
- int windowTopOnScreen = rootViewTopOnScreen - rootViewTopOnWindow;
- mCoordsOnWindow.set(
- Math.max(0, x - windowLeftOnScreen), Math.max(0, y - windowTopOnScreen));
- }
-
- /**
- * Performs the "show" animation on the floating popup.
- */
- private void runShowAnimation() {
- mShowAnimation.start();
- }
-
- /**
- * Performs the "dismiss" animation on the floating popup.
- */
- private void runDismissAnimation() {
- mDismissAnimation.start();
- }
-
- /**
- * Performs the "hide" animation on the floating popup.
- */
- private void runHideAnimation() {
- mHideAnimation.start();
- }
-
- private void cancelDismissAndHideAnimations() {
- mDismissAnimation.cancel();
- mHideAnimation.cancel();
- }
-
- private void cancelOverflowAnimations() {
- mContentContainer.clearAnimation();
- mMainPanel.animate().cancel();
- mOverflowPanel.animate().cancel();
- mToArrow.stop();
- mToOverflow.stop();
- }
-
- private void openOverflow() {
- final int targetWidth = mOverflowPanelSize.getWidth();
- final int targetHeight = mOverflowPanelSize.getHeight();
- final int startWidth = mContentContainer.getWidth();
- final int startHeight = mContentContainer.getHeight();
- final float startY = mContentContainer.getY();
- final float left = mContentContainer.getX();
- final float right = left + mContentContainer.getWidth();
- Animation widthAnimation = new Animation() {
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth));
- setWidth(mContentContainer, startWidth + deltaWidth);
- if (isInRTLMode()) {
- mContentContainer.setX(left);
-
- // Lock the panels in place.
- mMainPanel.setX(0);
- mOverflowPanel.setX(0);
- } else {
- mContentContainer.setX(right - mContentContainer.getWidth());
-
- // Offset the panels' positions so they look like they're locked in place
- // on the screen.
- mMainPanel.setX(mContentContainer.getWidth() - startWidth);
- mOverflowPanel.setX(mContentContainer.getWidth() - targetWidth);
- }
- }
- };
- Animation heightAnimation = new Animation() {
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- int deltaHeight = (int) (interpolatedTime * (targetHeight - startHeight));
- setHeight(mContentContainer, startHeight + deltaHeight);
- if (mOpenOverflowUpwards) {
- mContentContainer.setY(
- startY - (mContentContainer.getHeight() - startHeight));
- positionContentYCoordinatesIfOpeningOverflowUpwards();
- }
- }
- };
- final float overflowButtonStartX = mOverflowButton.getX();
- final float overflowButtonTargetX = isInRTLMode() ?
- overflowButtonStartX + targetWidth - mOverflowButton.getWidth() :
- overflowButtonStartX - targetWidth + mOverflowButton.getWidth();
- Animation overflowButtonAnimation = new Animation() {
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- float overflowButtonX = overflowButtonStartX
- + interpolatedTime * (overflowButtonTargetX - overflowButtonStartX);
- float deltaContainerWidth = isInRTLMode() ?
- 0 :
- mContentContainer.getWidth() - startWidth;
- float actualOverflowButtonX = overflowButtonX + deltaContainerWidth;
- mOverflowButton.setX(actualOverflowButtonX);
- }
- };
- widthAnimation.setInterpolator(mLogAccelerateInterpolator);
- widthAnimation.setDuration(getAdjustedDuration(250));
- heightAnimation.setInterpolator(mFastOutSlowInInterpolator);
- heightAnimation.setDuration(getAdjustedDuration(250));
- overflowButtonAnimation.setInterpolator(mFastOutSlowInInterpolator);
- overflowButtonAnimation.setDuration(getAdjustedDuration(250));
- mOpenOverflowAnimation.getAnimations().clear();
- mOpenOverflowAnimation.getAnimations().clear();
- mOpenOverflowAnimation.addAnimation(widthAnimation);
- mOpenOverflowAnimation.addAnimation(heightAnimation);
- mOpenOverflowAnimation.addAnimation(overflowButtonAnimation);
- mContentContainer.startAnimation(mOpenOverflowAnimation);
- mIsOverflowOpen = true;
- mMainPanel.animate()
- .alpha(0).withLayer()
- .setInterpolator(mLinearOutSlowInInterpolator)
- .setDuration(250)
- .start();
- mOverflowPanel.setAlpha(1); // fadeIn in 0ms.
- }
-
- private void closeOverflow() {
- final int targetWidth = mMainPanelSize.getWidth();
- final int startWidth = mContentContainer.getWidth();
- final float left = mContentContainer.getX();
- final float right = left + mContentContainer.getWidth();
- Animation widthAnimation = new Animation() {
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth));
- setWidth(mContentContainer, startWidth + deltaWidth);
- if (isInRTLMode()) {
- mContentContainer.setX(left);
-
- // Lock the panels in place.
- mMainPanel.setX(0);
- mOverflowPanel.setX(0);
- } else {
- mContentContainer.setX(right - mContentContainer.getWidth());
-
- // Offset the panels' positions so they look like they're locked in place
- // on the screen.
- mMainPanel.setX(mContentContainer.getWidth() - targetWidth);
- mOverflowPanel.setX(mContentContainer.getWidth() - startWidth);
- }
- }
- };
- final int targetHeight = mMainPanelSize.getHeight();
- final int startHeight = mContentContainer.getHeight();
- final float bottom = mContentContainer.getY() + mContentContainer.getHeight();
- Animation heightAnimation = new Animation() {
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- int deltaHeight = (int) (interpolatedTime * (targetHeight - startHeight));
- setHeight(mContentContainer, startHeight + deltaHeight);
- if (mOpenOverflowUpwards) {
- mContentContainer.setY(bottom - mContentContainer.getHeight());
- positionContentYCoordinatesIfOpeningOverflowUpwards();
- }
- }
- };
- final float overflowButtonStartX = mOverflowButton.getX();
- final float overflowButtonTargetX = isInRTLMode() ?
- overflowButtonStartX - startWidth + mOverflowButton.getWidth() :
- overflowButtonStartX + startWidth - mOverflowButton.getWidth();
- Animation overflowButtonAnimation = new Animation() {
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- float overflowButtonX = overflowButtonStartX
- + interpolatedTime * (overflowButtonTargetX - overflowButtonStartX);
- float deltaContainerWidth = isInRTLMode() ?
- 0 :
- mContentContainer.getWidth() - startWidth;
- float actualOverflowButtonX = overflowButtonX + deltaContainerWidth;
- mOverflowButton.setX(actualOverflowButtonX);
- }
- };
- widthAnimation.setInterpolator(mFastOutSlowInInterpolator);
- widthAnimation.setDuration(getAdjustedDuration(250));
- heightAnimation.setInterpolator(mLogAccelerateInterpolator);
- heightAnimation.setDuration(getAdjustedDuration(250));
- overflowButtonAnimation.setInterpolator(mFastOutSlowInInterpolator);
- overflowButtonAnimation.setDuration(getAdjustedDuration(250));
- mCloseOverflowAnimation.getAnimations().clear();
- mCloseOverflowAnimation.addAnimation(widthAnimation);
- mCloseOverflowAnimation.addAnimation(heightAnimation);
- mCloseOverflowAnimation.addAnimation(overflowButtonAnimation);
- mContentContainer.startAnimation(mCloseOverflowAnimation);
- mIsOverflowOpen = false;
- mMainPanel.animate()
- .alpha(1).withLayer()
- .setInterpolator(mFastOutLinearInInterpolator)
- .setDuration(100)
- .start();
- mOverflowPanel.animate()
- .alpha(0).withLayer()
- .setInterpolator(mLinearOutSlowInInterpolator)
- .setDuration(150)
- .start();
- }
-
- /**
- * Defines the position of the floating toolbar popup panels when transition animation has
- * stopped.
- */
- private void setPanelsStatesAtRestingPosition() {
- mOverflowButton.setEnabled(true);
- mOverflowPanel.awakenScrollBars();
-
- if (mIsOverflowOpen) {
- // Set open state.
- final Size containerSize = mOverflowPanelSize;
- setSize(mContentContainer, containerSize);
- mMainPanel.setAlpha(0);
- mMainPanel.setVisibility(View.INVISIBLE);
- mOverflowPanel.setAlpha(1);
- mOverflowPanel.setVisibility(View.VISIBLE);
- mOverflowButton.setImageDrawable(mArrow);
- mOverflowButton.setContentDescription(mContext.getString(
- R.string.floating_toolbar_close_overflow_description));
-
- // Update x-coordinates depending on RTL state.
- if (isInRTLMode()) {
- mContentContainer.setX(mMarginHorizontal); // align left
- mMainPanel.setX(0); // align left
- mOverflowButton.setX( // align right
- containerSize.getWidth() - mOverflowButtonSize.getWidth());
- mOverflowPanel.setX(0); // align left
- } else {
- mContentContainer.setX( // align right
- mPopupWindow.getWidth() -
- containerSize.getWidth() - mMarginHorizontal);
- mMainPanel.setX(-mContentContainer.getX()); // align right
- mOverflowButton.setX(0); // align left
- mOverflowPanel.setX(0); // align left
- }
-
- // Update y-coordinates depending on overflow's open direction.
- if (mOpenOverflowUpwards) {
- mContentContainer.setY(mMarginVertical); // align top
- mMainPanel.setY( // align bottom
- containerSize.getHeight() - mContentContainer.getHeight());
- mOverflowButton.setY( // align bottom
- containerSize.getHeight() - mOverflowButtonSize.getHeight());
- mOverflowPanel.setY(0); // align top
- } else {
- // opens downwards.
- mContentContainer.setY(mMarginVertical); // align top
- mMainPanel.setY(0); // align top
- mOverflowButton.setY(0); // align top
- mOverflowPanel.setY(mOverflowButtonSize.getHeight()); // align bottom
- }
- } else {
- // Overflow not open. Set closed state.
- final Size containerSize = mMainPanelSize;
- setSize(mContentContainer, containerSize);
- mMainPanel.setAlpha(1);
- mMainPanel.setVisibility(View.VISIBLE);
- mOverflowPanel.setAlpha(0);
- mOverflowPanel.setVisibility(View.INVISIBLE);
- mOverflowButton.setImageDrawable(mOverflow);
- mOverflowButton.setContentDescription(mContext.getString(
- R.string.floating_toolbar_open_overflow_description));
-
- if (hasOverflow()) {
- // Update x-coordinates depending on RTL state.
- if (isInRTLMode()) {
- mContentContainer.setX(mMarginHorizontal); // align left
- mMainPanel.setX(0); // align left
- mOverflowButton.setX(0); // align left
- mOverflowPanel.setX(0); // align left
- } else {
- mContentContainer.setX( // align right
- mPopupWindow.getWidth() -
- containerSize.getWidth() - mMarginHorizontal);
- mMainPanel.setX(0); // align left
- mOverflowButton.setX( // align right
- containerSize.getWidth() - mOverflowButtonSize.getWidth());
- mOverflowPanel.setX( // align right
- containerSize.getWidth() - mOverflowPanelSize.getWidth());
- }
-
- // Update y-coordinates depending on overflow's open direction.
- if (mOpenOverflowUpwards) {
- mContentContainer.setY( // align bottom
- mMarginVertical +
- mOverflowPanelSize.getHeight() - containerSize.getHeight());
- mMainPanel.setY(0); // align top
- mOverflowButton.setY(0); // align top
- mOverflowPanel.setY( // align bottom
- containerSize.getHeight() - mOverflowPanelSize.getHeight());
- } else {
- // opens downwards.
- mContentContainer.setY(mMarginVertical); // align top
- mMainPanel.setY(0); // align top
- mOverflowButton.setY(0); // align top
- mOverflowPanel.setY(mOverflowButtonSize.getHeight()); // align bottom
- }
- } else {
- // No overflow.
- mContentContainer.setX(mMarginHorizontal); // align left
- mContentContainer.setY(mMarginVertical); // align top
- mMainPanel.setX(0); // align left
- mMainPanel.setY(0); // align top
- }
- }
- }
-
- private void updateOverflowHeight(int suggestedHeight) {
- if (hasOverflow()) {
- final int maxItemSize = (suggestedHeight - mOverflowButtonSize.getHeight()) /
- mLineHeight;
- final int newHeight = calculateOverflowHeight(maxItemSize);
- if (mOverflowPanelSize.getHeight() != newHeight) {
- mOverflowPanelSize = new Size(mOverflowPanelSize.getWidth(), newHeight);
- }
- setSize(mOverflowPanel, mOverflowPanelSize);
- if (mIsOverflowOpen) {
- setSize(mContentContainer, mOverflowPanelSize);
- if (mOpenOverflowUpwards) {
- final int deltaHeight = mOverflowPanelSize.getHeight() - newHeight;
- mContentContainer.setY(mContentContainer.getY() + deltaHeight);
- mOverflowButton.setY(mOverflowButton.getY() - deltaHeight);
- }
- } else {
- setSize(mContentContainer, mMainPanelSize);
- }
- updatePopupSize();
- }
- }
-
- private void updatePopupSize() {
- int width = 0;
- int height = 0;
- if (mMainPanelSize != null) {
- width = Math.max(width, mMainPanelSize.getWidth());
- height = Math.max(height, mMainPanelSize.getHeight());
- }
- if (mOverflowPanelSize != null) {
- width = Math.max(width, mOverflowPanelSize.getWidth());
- height = Math.max(height, mOverflowPanelSize.getHeight());
- }
- mPopupWindow.setWidth(width + mMarginHorizontal * 2);
- mPopupWindow.setHeight(height + mMarginVertical * 2);
- maybeComputeTransitionDurationScale();
- }
-
- private void refreshViewPort() {
- mParent.getWindowVisibleDisplayFrame(mViewPortOnScreen);
- }
-
- private int getAdjustedToolbarWidth(int suggestedWidth) {
- int width = suggestedWidth;
- refreshViewPort();
- int maximumWidth = mViewPortOnScreen.width() - 2 * mParent.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
- if (width <= 0) {
- width = mParent.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width);
- }
- return Math.min(width, maximumWidth);
- }
-
- /**
- * Sets the touchable region of this popup to be zero. This means that all touch events on
- * this popup will go through to the surface behind it.
- */
- private void setZeroTouchableSurface() {
- mTouchableRegion.setEmpty();
- }
-
- /**
- * Sets the touchable region of this popup to be the area occupied by its content.
- */
- private void setContentAreaAsTouchableSurface() {
- Objects.requireNonNull(mMainPanelSize);
- final int width;
- final int height;
- if (mIsOverflowOpen) {
- Objects.requireNonNull(mOverflowPanelSize);
- width = mOverflowPanelSize.getWidth();
- height = mOverflowPanelSize.getHeight();
- } else {
- width = mMainPanelSize.getWidth();
- height = mMainPanelSize.getHeight();
- }
- mTouchableRegion.set(
- (int) mContentContainer.getX(),
- (int) mContentContainer.getY(),
- (int) mContentContainer.getX() + width,
- (int) mContentContainer.getY() + height);
- }
-
- /**
- * Make the touchable area of this popup be the area specified by mTouchableRegion.
- * This should be called after the popup window has been dismissed (dismiss/hide)
- * and is probably being re-shown with a new content root view.
- */
- private void setTouchableSurfaceInsetsComputer() {
- ViewTreeObserver viewTreeObserver = mPopupWindow.getContentView()
- .getRootView()
- .getViewTreeObserver();
- viewTreeObserver.removeOnComputeInternalInsetsListener(mInsetsComputer);
- viewTreeObserver.addOnComputeInternalInsetsListener(mInsetsComputer);
- }
-
- private boolean isInRTLMode() {
- return mContext.getApplicationInfo().hasRtlSupport()
- && mContext.getResources().getConfiguration().getLayoutDirection()
- == View.LAYOUT_DIRECTION_RTL;
- }
-
- private boolean hasOverflow() {
- return mOverflowPanelSize != null;
- }
-
- /**
- * Fits as many menu items in the main panel and returns a list of the menu items that
- * were not fit in.
- *
- * @return The menu items that are not included in this main panel.
- */
- public List<MenuItem> layoutMainPanelItems(
- List<MenuItem> menuItems, final int toolbarWidth) {
- Objects.requireNonNull(menuItems);
-
- int availableWidth = toolbarWidth;
-
- final LinkedList<MenuItem> remainingMenuItems = new LinkedList<>();
- // add the overflow menu items to the end of the remainingMenuItems list.
- final LinkedList<MenuItem> overflowMenuItems = new LinkedList();
- for (MenuItem menuItem : menuItems) {
- if (menuItem.getItemId() != android.R.id.textAssist
- && menuItem.requiresOverflow()) {
- overflowMenuItems.add(menuItem);
- } else {
- remainingMenuItems.add(menuItem);
- }
- }
- remainingMenuItems.addAll(overflowMenuItems);
-
- mMainPanel.removeAllViews();
- mMainPanel.setPaddingRelative(0, 0, 0, 0);
-
- int lastGroupId = -1;
- boolean isFirstItem = true;
- while (!remainingMenuItems.isEmpty()) {
- final MenuItem menuItem = remainingMenuItems.peek();
-
- // if this is the first item, regardless of requiresOverflow(), it should be
- // displayed on the main panel. Otherwise all items including this one will be
- // overflow items, and should be displayed in overflow panel.
- if(!isFirstItem && menuItem.requiresOverflow()) {
- break;
- }
-
- final boolean showIcon = isFirstItem && menuItem.getItemId() == R.id.textAssist;
- final View menuItemButton = createMenuItemButton(
- mContext, menuItem, mIconTextSpacing, showIcon);
- if (!showIcon && menuItemButton instanceof LinearLayout) {
- ((LinearLayout) menuItemButton).setGravity(Gravity.CENTER);
- }
-
- // Adding additional start padding for the first button to even out button spacing.
- if (isFirstItem) {
- menuItemButton.setPaddingRelative(
- (int) (1.5 * menuItemButton.getPaddingStart()),
- menuItemButton.getPaddingTop(),
- menuItemButton.getPaddingEnd(),
- menuItemButton.getPaddingBottom());
- }
-
- // Adding additional end padding for the last button to even out button spacing.
- boolean isLastItem = remainingMenuItems.size() == 1;
- if (isLastItem) {
- menuItemButton.setPaddingRelative(
- menuItemButton.getPaddingStart(),
- menuItemButton.getPaddingTop(),
- (int) (1.5 * menuItemButton.getPaddingEnd()),
- menuItemButton.getPaddingBottom());
- }
-
- menuItemButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
- final int menuItemButtonWidth = Math.min(
- menuItemButton.getMeasuredWidth(), toolbarWidth);
-
- // Check if we can fit an item while reserving space for the overflowButton.
- final boolean canFitWithOverflow =
- menuItemButtonWidth <=
- availableWidth - mOverflowButtonSize.getWidth();
- final boolean canFitNoOverflow =
- isLastItem && menuItemButtonWidth <= availableWidth;
- if (canFitWithOverflow || canFitNoOverflow) {
- setButtonTagAndClickListener(menuItemButton, menuItem);
- // Set tooltips for main panel items, but not overflow items (b/35726766).
- menuItemButton.setTooltipText(menuItem.getTooltipText());
- mMainPanel.addView(menuItemButton);
- final ViewGroup.LayoutParams params = menuItemButton.getLayoutParams();
- params.width = menuItemButtonWidth;
- menuItemButton.setLayoutParams(params);
- availableWidth -= menuItemButtonWidth;
- remainingMenuItems.pop();
- } else {
- break;
- }
- lastGroupId = menuItem.getGroupId();
- isFirstItem = false;
- }
-
- if (!remainingMenuItems.isEmpty()) {
- // Reserve space for overflowButton.
- mMainPanel.setPaddingRelative(0, 0, mOverflowButtonSize.getWidth(), 0);
- }
-
- mMainPanelSize = measure(mMainPanel);
- return remainingMenuItems;
- }
-
- private void layoutOverflowPanelItems(List<MenuItem> menuItems) {
- ArrayAdapter<MenuItem> overflowPanelAdapter =
- (ArrayAdapter<MenuItem>) mOverflowPanel.getAdapter();
- overflowPanelAdapter.clear();
- final int size = menuItems.size();
- for (int i = 0; i < size; i++) {
- overflowPanelAdapter.add(menuItems.get(i));
- }
- mOverflowPanel.setAdapter(overflowPanelAdapter);
- if (mOpenOverflowUpwards) {
- mOverflowPanel.setY(0);
- } else {
- mOverflowPanel.setY(mOverflowButtonSize.getHeight());
- }
-
- int width = Math.max(getOverflowWidth(), mOverflowButtonSize.getWidth());
- int height = calculateOverflowHeight(MAX_OVERFLOW_SIZE);
- mOverflowPanelSize = new Size(width, height);
- setSize(mOverflowPanel, mOverflowPanelSize);
- }
-
- /**
- * Resets the content container and appropriately position it's panels.
- */
- private void preparePopupContent() {
- mContentContainer.removeAllViews();
-
- // Add views in the specified order so they stack up as expected.
- // Order: overflowPanel, mainPanel, overflowButton.
- if (hasOverflow()) {
- mContentContainer.addView(mOverflowPanel);
- }
- mContentContainer.addView(mMainPanel);
- if (hasOverflow()) {
- mContentContainer.addView(mOverflowButton);
- }
- setPanelsStatesAtRestingPosition();
- setContentAreaAsTouchableSurface();
-
- // The positioning of contents in RTL is wrong when the view is first rendered.
- // Hide the view and post a runnable to recalculate positions and render the view.
- // TODO: Investigate why this happens and fix.
- if (isInRTLMode()) {
- mContentContainer.setAlpha(0);
- mContentContainer.post(mPreparePopupContentRTLHelper);
- }
- }
-
- /**
- * Clears out the panels and their container. Resets their calculated sizes.
- */
- private void clearPanels() {
- mOverflowPanelSize = null;
- mMainPanelSize = null;
- mIsOverflowOpen = false;
- mMainPanel.removeAllViews();
- ArrayAdapter<MenuItem> overflowPanelAdapter =
- (ArrayAdapter<MenuItem>) mOverflowPanel.getAdapter();
- overflowPanelAdapter.clear();
- mOverflowPanel.setAdapter(overflowPanelAdapter);
- mContentContainer.removeAllViews();
- }
-
- private void positionContentYCoordinatesIfOpeningOverflowUpwards() {
- if (mOpenOverflowUpwards) {
- mMainPanel.setY(mContentContainer.getHeight() - mMainPanelSize.getHeight());
- mOverflowButton.setY(mContentContainer.getHeight() - mOverflowButton.getHeight());
- mOverflowPanel.setY(mContentContainer.getHeight() - mOverflowPanelSize.getHeight());
- }
- }
-
- private int getOverflowWidth() {
- int overflowWidth = 0;
- final int count = mOverflowPanel.getAdapter().getCount();
- for (int i = 0; i < count; i++) {
- MenuItem menuItem = (MenuItem) mOverflowPanel.getAdapter().getItem(i);
- overflowWidth =
- Math.max(mOverflowPanelViewHelper.calculateWidth(menuItem), overflowWidth);
- }
- return overflowWidth;
- }
-
- private int calculateOverflowHeight(int maxItemSize) {
- // Maximum of 4 items, minimum of 2 if the overflow has to scroll.
- int actualSize = Math.min(
- MAX_OVERFLOW_SIZE,
- Math.min(
- Math.max(MIN_OVERFLOW_SIZE, maxItemSize),
- mOverflowPanel.getCount()));
- int extension = 0;
- if (actualSize < mOverflowPanel.getCount()) {
- // The overflow will require scrolling to get to all the items.
- // Extend the height so that part of the hidden items is displayed.
- extension = (int) (mLineHeight * 0.5f);
- }
- return actualSize * mLineHeight
- + mOverflowButtonSize.getHeight()
- + extension;
- }
-
- private void setButtonTagAndClickListener(View menuItemButton, MenuItem menuItem) {
- menuItemButton.setTag(MenuItemRepr.of(menuItem));
- menuItemButton.setOnClickListener(mMenuItemButtonOnClickListener);
- }
-
- /**
- * NOTE: Use only in android.view.animation.* animations. Do not use in android.animation.*
- * animations. See comment about this in the code.
- */
- private int getAdjustedDuration(int originalDuration) {
- if (mTransitionDurationScale < 150) {
- // For smaller transition, decrease the time.
- return Math.max(originalDuration - 50, 0);
- } else if (mTransitionDurationScale > 300) {
- // For bigger transition, increase the time.
- return originalDuration + 50;
- }
-
- // Scale the animation duration with getDurationScale(). This allows
- // android.view.animation.* animations to scale just like android.animation.* animations
- // when animator duration scale is adjusted in "Developer Options".
- // For this reason, do not use this method for android.animation.* animations.
- return (int) (originalDuration * ValueAnimator.getDurationScale());
- }
-
- private void maybeComputeTransitionDurationScale() {
- if (mMainPanelSize != null && mOverflowPanelSize != null) {
- int w = mMainPanelSize.getWidth() - mOverflowPanelSize.getWidth();
- int h = mOverflowPanelSize.getHeight() - mMainPanelSize.getHeight();
- mTransitionDurationScale = (int) (Math.sqrt(w * w + h * h) /
- mContentContainer.getContext().getResources().getDisplayMetrics().density);
- }
- }
-
- private ViewGroup createMainPanel() {
- ViewGroup mainPanel = new LinearLayout(mContext) {
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- if (isOverflowAnimating()) {
- // Update widthMeasureSpec to make sure that this view is not clipped
- // as we offset it's coordinates with respect to it's parent.
- widthMeasureSpec = MeasureSpec.makeMeasureSpec(
- mMainPanelSize.getWidth(),
- MeasureSpec.EXACTLY);
- }
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- // Intercept the touch event while the overflow is animating.
- return isOverflowAnimating();
- }
- };
- return mainPanel;
- }
-
- private ImageButton createOverflowButton() {
- final ImageButton overflowButton = (ImageButton) LayoutInflater.from(mContext)
- .inflate(R.layout.floating_popup_overflow_button, null);
- overflowButton.setImageDrawable(mOverflow);
- overflowButton.setOnClickListener(v -> {
- if (mIsOverflowOpen) {
- overflowButton.setImageDrawable(mToOverflow);
- mToOverflow.start();
- closeOverflow();
- } else {
- overflowButton.setImageDrawable(mToArrow);
- mToArrow.start();
- openOverflow();
- }
- });
- return overflowButton;
- }
-
- private OverflowPanel createOverflowPanel() {
- final OverflowPanel overflowPanel = new OverflowPanel(this);
- overflowPanel.setLayoutParams(new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- overflowPanel.setDivider(null);
- overflowPanel.setDividerHeight(0);
-
- final ArrayAdapter adapter =
- new ArrayAdapter<MenuItem>(mContext, 0) {
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- return mOverflowPanelViewHelper.getView(
- getItem(position), mOverflowPanelSize.getWidth(), convertView);
- }
- };
- overflowPanel.setAdapter(adapter);
-
- overflowPanel.setOnItemClickListener((parent, view, position, id) -> {
- MenuItem menuItem = (MenuItem) overflowPanel.getAdapter().getItem(position);
- if (mOnMenuItemClickListener != null) {
- mOnMenuItemClickListener.onMenuItemClick(menuItem);
- }
- });
-
- return overflowPanel;
- }
-
- private boolean isOverflowAnimating() {
- final boolean overflowOpening = mOpenOverflowAnimation.hasStarted()
- && !mOpenOverflowAnimation.hasEnded();
- final boolean overflowClosing = mCloseOverflowAnimation.hasStarted()
- && !mCloseOverflowAnimation.hasEnded();
- return overflowOpening || overflowClosing;
- }
-
- private Animation.AnimationListener createOverflowAnimationListener() {
- Animation.AnimationListener listener = new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
- // Disable the overflow button while it's animating.
- // It will be re-enabled when the animation stops.
- mOverflowButton.setEnabled(false);
- // Ensure both panels have visibility turned on when the overflow animation
- // starts.
- mMainPanel.setVisibility(View.VISIBLE);
- mOverflowPanel.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- // Posting this because it seems like this is called before the animation
- // actually ends.
- mContentContainer.post(() -> {
- setPanelsStatesAtRestingPosition();
- setContentAreaAsTouchableSurface();
- });
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
- };
- return listener;
- }
-
- private static Size measure(View view) {
- Preconditions.checkState(view.getParent() == null);
- view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
- return new Size(view.getMeasuredWidth(), view.getMeasuredHeight());
- }
-
- private static void setSize(View view, int width, int height) {
- view.setMinimumWidth(width);
- view.setMinimumHeight(height);
- ViewGroup.LayoutParams params = view.getLayoutParams();
- params = (params == null) ? new ViewGroup.LayoutParams(0, 0) : params;
- params.width = width;
- params.height = height;
- view.setLayoutParams(params);
- }
-
- private static void setSize(View view, Size size) {
- setSize(view, size.getWidth(), size.getHeight());
- }
-
- private static void setWidth(View view, int width) {
- ViewGroup.LayoutParams params = view.getLayoutParams();
- setSize(view, width, params.height);
- }
-
- private static void setHeight(View view, int height) {
- ViewGroup.LayoutParams params = view.getLayoutParams();
- setSize(view, params.width, height);
- }
-
- /**
- * A custom ListView for the overflow panel.
- */
- private static final class OverflowPanel extends ListView {
-
- private final FloatingToolbarPopup mPopup;
-
- OverflowPanel(FloatingToolbarPopup popup) {
- super(Objects.requireNonNull(popup).mContext);
- this.mPopup = popup;
- setScrollBarDefaultDelayBeforeFade(ViewConfiguration.getScrollDefaultDelay() * 3);
- setScrollIndicators(View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- // Update heightMeasureSpec to make sure that this view is not clipped
- // as we offset it's coordinates with respect to it's parent.
- int height = mPopup.mOverflowPanelSize.getHeight()
- - mPopup.mOverflowButtonSize.getHeight();
- heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (mPopup.isOverflowAnimating()) {
- // Eat the touch event.
- return true;
- }
- return super.dispatchTouchEvent(ev);
- }
-
- @Override
- protected boolean awakenScrollBars() {
- return super.awakenScrollBars();
- }
- }
-
- /**
- * A custom interpolator used for various floating toolbar animations.
- */
- private static final class LogAccelerateInterpolator implements Interpolator {
-
- private static final int BASE = 100;
- private static final float LOGS_SCALE = 1f / computeLog(1, BASE);
-
- private static float computeLog(float t, int base) {
- return (float) (1 - Math.pow(base, -t));
- }
-
- @Override
- public float getInterpolation(float t) {
- return 1 - computeLog(1 - t, BASE) * LOGS_SCALE;
- }
- }
-
- /**
- * A helper for generating views for the overflow panel.
- */
- private static final class OverflowPanelViewHelper {
-
- private final View mCalculator;
- private final int mIconTextSpacing;
- private final int mSidePadding;
-
- private final Context mContext;
-
- public OverflowPanelViewHelper(Context context, int iconTextSpacing) {
- mContext = Objects.requireNonNull(context);
- mIconTextSpacing = iconTextSpacing;
- mSidePadding = context.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_overflow_side_padding);
- mCalculator = createMenuButton(null);
- }
-
- public View getView(MenuItem menuItem, int minimumWidth, View convertView) {
- Objects.requireNonNull(menuItem);
- if (convertView != null) {
- updateMenuItemButton(
- convertView, menuItem, mIconTextSpacing, shouldShowIcon(menuItem));
- } else {
- convertView = createMenuButton(menuItem);
- }
- convertView.setMinimumWidth(minimumWidth);
- return convertView;
- }
-
- public int calculateWidth(MenuItem menuItem) {
- updateMenuItemButton(
- mCalculator, menuItem, mIconTextSpacing, shouldShowIcon(menuItem));
- mCalculator.measure(
- View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
- return mCalculator.getMeasuredWidth();
- }
-
- private View createMenuButton(MenuItem menuItem) {
- View button = createMenuItemButton(
- mContext, menuItem, mIconTextSpacing, shouldShowIcon(menuItem));
- button.setPadding(mSidePadding, 0, mSidePadding, 0);
- return button;
- }
-
- private boolean shouldShowIcon(MenuItem menuItem) {
- if (menuItem != null) {
- return menuItem.getGroupId() == android.R.id.textAssist;
- }
- return false;
- }
- }
- }
-
- /**
- * Represents the identity of a MenuItem that is rendered in a FloatingToolbarPopup.
- */
- @VisibleForTesting
- public static final class MenuItemRepr {
-
- public final int itemId;
- public final int groupId;
- @Nullable public final String title;
- @Nullable private final Drawable mIcon;
-
- private MenuItemRepr(
- int itemId, int groupId, @Nullable CharSequence title, @Nullable Drawable icon) {
- this.itemId = itemId;
- this.groupId = groupId;
- this.title = (title == null) ? null : title.toString();
- mIcon = icon;
- }
-
- /**
- * Creates an instance of MenuItemRepr for the specified menu item.
- */
- public static MenuItemRepr of(MenuItem menuItem) {
- return new MenuItemRepr(
- menuItem.getItemId(),
- menuItem.getGroupId(),
- menuItem.getTitle(),
- menuItem.getIcon());
- }
-
- /**
- * Returns this object's hashcode.
- */
- @Override
- public int hashCode() {
- return Objects.hash(itemId, groupId, title, mIcon);
- }
-
- /**
- * Returns true if this object is the same as the specified object.
- */
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof MenuItemRepr)) {
- return false;
- }
- final MenuItemRepr other = (MenuItemRepr) o;
- return itemId == other.itemId
- && groupId == other.groupId
- && TextUtils.equals(title, other.title)
- // Many Drawables (icons) do not implement equals(). Using equals() here instead
- // of reference comparisons in case a Drawable subclass implements equals().
- && Objects.equals(mIcon, other.mIcon);
- }
-
- /**
- * Returns true if the two menu item collections are the same based on MenuItemRepr.
- */
- public static boolean reprEquals(
- Collection<MenuItem> menuItems1, Collection<MenuItem> menuItems2) {
- if (menuItems1.size() != menuItems2.size()) {
- return false;
- }
-
- final Iterator<MenuItem> menuItems2Iter = menuItems2.iterator();
- for (MenuItem menuItem1 : menuItems1) {
- final MenuItem menuItem2 = menuItems2Iter.next();
- if (!MenuItemRepr.of(menuItem1).equals(MenuItemRepr.of(menuItem2))) {
- return false;
- }
- }
-
- return true;
- }
- }
-
- /**
- * Creates and returns a menu button for the specified menu item.
- */
- private static View createMenuItemButton(
- Context context, MenuItem menuItem, int iconTextSpacing, boolean showIcon) {
- final View menuItemButton = LayoutInflater.from(context)
- .inflate(R.layout.floating_popup_menu_button, null);
- if (menuItem != null) {
- updateMenuItemButton(menuItemButton, menuItem, iconTextSpacing, showIcon);
- }
- return menuItemButton;
- }
-
- /**
- * Updates the specified menu item button with the specified menu item data.
- */
- private static void updateMenuItemButton(
- View menuItemButton, MenuItem menuItem, int iconTextSpacing, boolean showIcon) {
- final TextView buttonText = menuItemButton.findViewById(
- R.id.floating_toolbar_menu_item_text);
- buttonText.setEllipsize(null);
- if (TextUtils.isEmpty(menuItem.getTitle())) {
- buttonText.setVisibility(View.GONE);
- } else {
- buttonText.setVisibility(View.VISIBLE);
- buttonText.setText(menuItem.getTitle());
- }
- final ImageView buttonIcon = menuItemButton.findViewById(
- R.id.floating_toolbar_menu_item_image);
- if (menuItem.getIcon() == null || !showIcon) {
- buttonIcon.setVisibility(View.GONE);
- if (buttonText != null) {
- buttonText.setPaddingRelative(0, 0, 0, 0);
- }
- } else {
- buttonIcon.setVisibility(View.VISIBLE);
- buttonIcon.setImageDrawable(menuItem.getIcon());
- if (buttonText != null) {
- buttonText.setPaddingRelative(iconTextSpacing, 0, 0, 0);
- }
- }
- final CharSequence contentDescription = menuItem.getContentDescription();
- if (TextUtils.isEmpty(contentDescription)) {
- menuItemButton.setContentDescription(menuItem.getTitle());
- } else {
- menuItemButton.setContentDescription(contentDescription);
- }
- }
-
- private static ViewGroup createContentContainer(Context context) {
- ViewGroup contentContainer = (ViewGroup) LayoutInflater.from(context)
- .inflate(R.layout.floating_popup_container, null);
- contentContainer.setLayoutParams(new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
- contentContainer.setTag(FLOATING_TOOLBAR_TAG);
- contentContainer.setClipToOutline(true);
- return contentContainer;
- }
-
- private static PopupWindow createPopupWindow(ViewGroup content) {
- ViewGroup popupContentHolder = new LinearLayout(content.getContext());
- PopupWindow popupWindow = new PopupWindow(popupContentHolder);
- // TODO: Use .setIsLaidOutInScreen(true) instead of .setClippingEnabled(false)
- // unless FLAG_LAYOUT_IN_SCREEN has any unintentional side-effects.
- popupWindow.setClippingEnabled(false);
- popupWindow.setWindowLayoutType(
- WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
- popupWindow.setAnimationStyle(0);
- popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
- content.setLayoutParams(new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
- popupContentHolder.addView(content);
- return popupWindow;
- }
-
- /**
- * Creates an "appear" animation for the specified view.
- *
- * @param view The view to animate
- */
- private static AnimatorSet createEnterAnimation(View view) {
- AnimatorSet animation = new AnimatorSet();
- animation.playTogether(
- ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(150));
- return animation;
- }
-
- /**
- * Creates a "disappear" animation for the specified view.
- *
- * @param view The view to animate
- * @param startDelay The start delay of the animation
- * @param listener The animation listener
- */
- private static AnimatorSet createExitAnimation(
- View view, int startDelay, Animator.AnimatorListener listener) {
- AnimatorSet animation = new AnimatorSet();
- animation.playTogether(
- ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0).setDuration(100));
- animation.setStartDelay(startDelay);
- animation.addListener(listener);
- return animation;
- }
-
- /**
- * Returns a re-themed context with controlled look and feel for views.
- */
- private static Context applyDefaultTheme(Context originalContext) {
- TypedArray a = originalContext.obtainStyledAttributes(new int[]{R.attr.isLightTheme});
- boolean isLightTheme = a.getBoolean(0, true);
- int themeId
- = isLightTheme ? R.style.Theme_DeviceDefault_Light : R.style.Theme_DeviceDefault;
- a.recycle();
- return new ContextThemeWrapper(originalContext, themeId);
- }
}
diff --git a/core/java/com/android/internal/widget/FloatingToolbarPopup.java b/core/java/com/android/internal/widget/FloatingToolbarPopup.java
new file mode 100644
index 0000000..e0388f6
--- /dev/null
+++ b/core/java/com/android/internal/widget/FloatingToolbarPopup.java
@@ -0,0 +1,1610 @@
+/*
+ * 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.internal.widget;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.Size;
+import android.view.ContextThemeWrapper;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.view.animation.Transformation;
+import android.widget.ArrayAdapter;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A popup window used by the floating toolbar.
+ *
+ * This class is responsible for the rendering/animation of the floating toolbar.
+ * It holds 2 panels (i.e. main panel and overflow panel) and an overflow button
+ * to transition between panels.
+ */
+public final class FloatingToolbarPopup {
+
+ /* Minimum and maximum number of items allowed in the overflow. */
+ private static final int MIN_OVERFLOW_SIZE = 2;
+ private static final int MAX_OVERFLOW_SIZE = 4;
+
+ private final Context mContext;
+ private final View mParent; // Parent for the popup window.
+ private final PopupWindow mPopupWindow;
+
+ /* Margins between the popup window and its content. */
+ private final int mMarginHorizontal;
+ private final int mMarginVertical;
+
+ /* View components */
+ private final ViewGroup mContentContainer; // holds all contents.
+ private final ViewGroup mMainPanel; // holds menu items that are initially displayed.
+ // holds menu items hidden in the overflow.
+ private final FloatingToolbarPopup.OverflowPanel mOverflowPanel;
+ private final ImageButton mOverflowButton; // opens/closes the overflow.
+ /* overflow button drawables. */
+ private final Drawable mArrow;
+ private final Drawable mOverflow;
+ private final AnimatedVectorDrawable mToArrow;
+ private final AnimatedVectorDrawable mToOverflow;
+
+ private final FloatingToolbarPopup.OverflowPanelViewHelper
+ mOverflowPanelViewHelper;
+
+ /* Animation interpolators. */
+ private final Interpolator mLogAccelerateInterpolator;
+ private final Interpolator mFastOutSlowInInterpolator;
+ private final Interpolator mLinearOutSlowInInterpolator;
+ private final Interpolator mFastOutLinearInInterpolator;
+
+ /* Animations. */
+ private final AnimatorSet mShowAnimation;
+ private final AnimatorSet mDismissAnimation;
+ private final AnimatorSet mHideAnimation;
+ private final AnimationSet mOpenOverflowAnimation;
+ private final AnimationSet mCloseOverflowAnimation;
+ private final Animation.AnimationListener mOverflowAnimationListener;
+
+ private final Rect mViewPortOnScreen = new Rect(); // portion of screen we can draw in.
+ private final Point mCoordsOnWindow = new Point(); // popup window coordinates.
+ /* Temporary data holders. Reset values before using. */
+ private final int[] mTmpCoords = new int[2];
+
+ private final Region mTouchableRegion = new Region();
+ private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer =
+ info -> {
+ info.contentInsets.setEmpty();
+ info.visibleInsets.setEmpty();
+ info.touchableRegion.set(mTouchableRegion);
+ info.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ };
+
+ private final int mLineHeight;
+ private final int mIconTextSpacing;
+
+ /**
+ * @see FloatingToolbarPopup.OverflowPanelViewHelper#preparePopupContent().
+ */
+ private final Runnable mPreparePopupContentRTLHelper = new Runnable() {
+ @Override
+ public void run() {
+ setPanelsStatesAtRestingPosition();
+ setContentAreaAsTouchableSurface();
+ mContentContainer.setAlpha(1);
+ }
+ };
+
+ private boolean mDismissed = true; // tracks whether this popup is dismissed or dismissing.
+ private boolean mHidden; // tracks whether this popup is hidden or hiding.
+
+ /* Calculated sizes for panels and overflow button. */
+ private final Size mOverflowButtonSize;
+ private Size mOverflowPanelSize; // Should be null when there is no overflow.
+ private Size mMainPanelSize;
+
+ /* Menu items and click listeners */
+ private final Map<MenuItemRepr, MenuItem> mMenuItems = new LinkedHashMap<>();
+ private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener;
+ private final View.OnClickListener mMenuItemButtonOnClickListener =
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mOnMenuItemClickListener == null) {
+ return;
+ }
+ final Object tag = v.getTag();
+ if (!(tag instanceof MenuItemRepr)) {
+ return;
+ }
+ final MenuItem menuItem = mMenuItems.get((MenuItemRepr) tag);
+ if (menuItem == null) {
+ return;
+ }
+ mOnMenuItemClickListener.onMenuItemClick(menuItem);
+ }
+ };
+
+ private boolean mOpenOverflowUpwards; // Whether the overflow opens upwards or downwards.
+ private boolean mIsOverflowOpen;
+
+ private int mTransitionDurationScale; // Used to scale the toolbar transition duration.
+
+ /**
+ * Initializes a new floating toolbar popup.
+ *
+ * @param parent A parent view to get the {@link android.view.View#getWindowToken()} token
+ * from.
+ */
+ public FloatingToolbarPopup(Context context, View parent) {
+ mParent = Objects.requireNonNull(parent);
+ mContext = applyDefaultTheme(context);
+ mContentContainer = createContentContainer(context);
+ mPopupWindow = createPopupWindow(mContentContainer);
+ mMarginHorizontal = parent.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
+ mMarginVertical = parent.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_vertical_margin);
+ mLineHeight = context.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_height);
+ mIconTextSpacing = context.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_icon_text_spacing);
+
+ // Interpolators
+ mLogAccelerateInterpolator = new FloatingToolbarPopup.LogAccelerateInterpolator();
+ mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
+ mContext, android.R.interpolator.fast_out_slow_in);
+ mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(
+ mContext, android.R.interpolator.linear_out_slow_in);
+ mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(
+ mContext, android.R.interpolator.fast_out_linear_in);
+
+ // Drawables. Needed for views.
+ mArrow = mContext.getResources()
+ .getDrawable(R.drawable.ft_avd_tooverflow, mContext.getTheme());
+ mArrow.setAutoMirrored(true);
+ mOverflow = mContext.getResources()
+ .getDrawable(R.drawable.ft_avd_toarrow, mContext.getTheme());
+ mOverflow.setAutoMirrored(true);
+ mToArrow = (AnimatedVectorDrawable) mContext.getResources()
+ .getDrawable(R.drawable.ft_avd_toarrow_animation, mContext.getTheme());
+ mToArrow.setAutoMirrored(true);
+ mToOverflow = (AnimatedVectorDrawable) mContext.getResources()
+ .getDrawable(R.drawable.ft_avd_tooverflow_animation, mContext.getTheme());
+ mToOverflow.setAutoMirrored(true);
+
+ // Views
+ mOverflowButton = createOverflowButton();
+ mOverflowButtonSize = measure(mOverflowButton);
+ mMainPanel = createMainPanel();
+ mOverflowPanelViewHelper =
+ new FloatingToolbarPopup.OverflowPanelViewHelper(mContext, mIconTextSpacing);
+ mOverflowPanel = createOverflowPanel();
+
+ // Animation. Need views.
+ mOverflowAnimationListener = createOverflowAnimationListener();
+ mOpenOverflowAnimation = new AnimationSet(true);
+ mOpenOverflowAnimation.setAnimationListener(mOverflowAnimationListener);
+ mCloseOverflowAnimation = new AnimationSet(true);
+ mCloseOverflowAnimation.setAnimationListener(mOverflowAnimationListener);
+ mShowAnimation = createEnterAnimation(mContentContainer);
+ mDismissAnimation = createExitAnimation(
+ mContentContainer,
+ 150, // startDelay
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPopupWindow.dismiss();
+ mContentContainer.removeAllViews();
+ }
+ });
+ mHideAnimation = createExitAnimation(
+ mContentContainer,
+ 0, // startDelay
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPopupWindow.dismiss();
+ }
+ });
+ }
+
+ /**
+ * Makes this toolbar "outside touchable" and sets the onDismissListener.
+ *
+ * @param outsideTouchable if true, the popup will be made "outside touchable" and
+ * "non focusable". The reverse will happen if false.
+ * @param onDismiss
+ *
+ * @return true if the "outsideTouchable" setting was modified. Otherwise returns false
+ *
+ * @see PopupWindow#setOutsideTouchable(boolean)
+ * @see PopupWindow#setFocusable(boolean)
+ * @see PopupWindow.OnDismissListener
+ */
+ public boolean setOutsideTouchable(
+ boolean outsideTouchable, @Nullable PopupWindow.OnDismissListener onDismiss) {
+ boolean ret = false;
+ if (mPopupWindow.isOutsideTouchable() ^ outsideTouchable) {
+ mPopupWindow.setOutsideTouchable(outsideTouchable);
+ mPopupWindow.setFocusable(!outsideTouchable);
+ mPopupWindow.update();
+ ret = true;
+ }
+ mPopupWindow.setOnDismissListener(onDismiss);
+ return ret;
+ }
+
+ /**
+ * Lays out buttons for the specified menu items.
+ * Requires a subsequent call to {@link FloatingToolbar#show()} to show the items.
+ */
+ public void layoutMenuItems(
+ List<MenuItem> menuItems,
+ MenuItem.OnMenuItemClickListener menuItemClickListener,
+ int suggestedWidth) {
+ cancelOverflowAnimations();
+ clearPanels();
+ updateMenuItems(menuItems, menuItemClickListener);
+ menuItems = layoutMainPanelItems(menuItems, getAdjustedToolbarWidth(suggestedWidth));
+ if (!menuItems.isEmpty()) {
+ // Add remaining items to the overflow.
+ layoutOverflowPanelItems(menuItems);
+ }
+ updatePopupSize();
+ }
+
+ /**
+ * Updates the popup's menu items without rebuilding the widget.
+ * Use in place of layoutMenuItems() when the popup's views need not be reconstructed.
+ *
+ * @see #isLayoutRequired(List<MenuItem>)
+ */
+ public void updateMenuItems(
+ List<MenuItem> menuItems, MenuItem.OnMenuItemClickListener menuItemClickListener) {
+ mMenuItems.clear();
+ for (MenuItem menuItem : menuItems) {
+ mMenuItems.put(MenuItemRepr.of(menuItem), menuItem);
+ }
+ mOnMenuItemClickListener = menuItemClickListener;
+ }
+
+ /**
+ * Returns true if this popup needs a relayout to properly render the specified menu items.
+ */
+ public boolean isLayoutRequired(List<MenuItem> menuItems) {
+ return !MenuItemRepr.reprEquals(menuItems, mMenuItems.values());
+ }
+
+ /**
+ * Shows this popup at the specified coordinates.
+ * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
+ */
+ public void show(Rect contentRectOnScreen) {
+ Objects.requireNonNull(contentRectOnScreen);
+
+ if (isShowing()) {
+ return;
+ }
+
+ mHidden = false;
+ mDismissed = false;
+ cancelDismissAndHideAnimations();
+ cancelOverflowAnimations();
+
+ refreshCoordinatesAndOverflowDirection(contentRectOnScreen);
+ preparePopupContent();
+ // We need to specify the position in window coordinates.
+ // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can
+ // specify the popup position in screen coordinates.
+ mPopupWindow.showAtLocation(
+ mParent, Gravity.NO_GRAVITY, mCoordsOnWindow.x, mCoordsOnWindow.y);
+ setTouchableSurfaceInsetsComputer();
+ runShowAnimation();
+ }
+
+ /**
+ * Gets rid of this popup. If the popup isn't currently showing, this will be a no-op.
+ */
+ public void dismiss() {
+ if (mDismissed) {
+ return;
+ }
+
+ mHidden = false;
+ mDismissed = true;
+ mHideAnimation.cancel();
+
+ runDismissAnimation();
+ setZeroTouchableSurface();
+ }
+
+ /**
+ * Hides this popup. This is a no-op if this popup is not showing.
+ * Use {@link #isHidden()} to distinguish between a hidden and a dismissed popup.
+ */
+ public void hide() {
+ if (!isShowing()) {
+ return;
+ }
+
+ mHidden = true;
+ runHideAnimation();
+ setZeroTouchableSurface();
+ }
+
+ /**
+ * Returns {@code true} if this popup is currently showing. {@code false} otherwise.
+ */
+ public boolean isShowing() {
+ return !mDismissed && !mHidden;
+ }
+
+ /**
+ * Returns {@code true} if this popup is currently hidden. {@code false} otherwise.
+ */
+ public boolean isHidden() {
+ return mHidden;
+ }
+
+ /**
+ * Updates the coordinates of this popup.
+ * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
+ * This is a no-op if this popup is not showing.
+ */
+ public void updateCoordinates(Rect contentRectOnScreen) {
+ Objects.requireNonNull(contentRectOnScreen);
+
+ if (!isShowing() || !mPopupWindow.isShowing()) {
+ return;
+ }
+
+ cancelOverflowAnimations();
+ refreshCoordinatesAndOverflowDirection(contentRectOnScreen);
+ preparePopupContent();
+ // We need to specify the position in window coordinates.
+ // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can
+ // specify the popup position in screen coordinates.
+ mPopupWindow.update(
+ mCoordsOnWindow.x, mCoordsOnWindow.y,
+ mPopupWindow.getWidth(), mPopupWindow.getHeight());
+ }
+
+ private void refreshCoordinatesAndOverflowDirection(Rect contentRectOnScreen) {
+ refreshViewPort();
+
+ // Initialize x ensuring that the toolbar isn't rendered behind the nav bar in
+ // landscape.
+ final int x = Math.min(
+ contentRectOnScreen.centerX() - mPopupWindow.getWidth() / 2,
+ mViewPortOnScreen.right - mPopupWindow.getWidth());
+
+ final int y;
+
+ final int availableHeightAboveContent =
+ contentRectOnScreen.top - mViewPortOnScreen.top;
+ final int availableHeightBelowContent =
+ mViewPortOnScreen.bottom - contentRectOnScreen.bottom;
+
+ final int margin = 2 * mMarginVertical;
+ final int toolbarHeightWithVerticalMargin = mLineHeight + margin;
+
+ if (!hasOverflow()) {
+ if (availableHeightAboveContent >= toolbarHeightWithVerticalMargin) {
+ // There is enough space at the top of the content.
+ y = contentRectOnScreen.top - toolbarHeightWithVerticalMargin;
+ } else if (availableHeightBelowContent >= toolbarHeightWithVerticalMargin) {
+ // There is enough space at the bottom of the content.
+ y = contentRectOnScreen.bottom;
+ } else if (availableHeightBelowContent >= mLineHeight) {
+ // Just enough space to fit the toolbar with no vertical margins.
+ y = contentRectOnScreen.bottom - mMarginVertical;
+ } else {
+ // Not enough space. Prefer to position as high as possible.
+ y = Math.max(
+ mViewPortOnScreen.top,
+ contentRectOnScreen.top - toolbarHeightWithVerticalMargin);
+ }
+ } else {
+ // Has an overflow.
+ final int minimumOverflowHeightWithMargin =
+ calculateOverflowHeight(MIN_OVERFLOW_SIZE) + margin;
+ final int availableHeightThroughContentDown =
+ mViewPortOnScreen.bottom - contentRectOnScreen.top
+ + toolbarHeightWithVerticalMargin;
+ final int availableHeightThroughContentUp =
+ contentRectOnScreen.bottom - mViewPortOnScreen.top
+ + toolbarHeightWithVerticalMargin;
+
+ if (availableHeightAboveContent >= minimumOverflowHeightWithMargin) {
+ // There is enough space at the top of the content rect for the overflow.
+ // Position above and open upwards.
+ updateOverflowHeight(availableHeightAboveContent - margin);
+ y = contentRectOnScreen.top - mPopupWindow.getHeight();
+ mOpenOverflowUpwards = true;
+ } else if (availableHeightAboveContent >= toolbarHeightWithVerticalMargin
+ && availableHeightThroughContentDown >= minimumOverflowHeightWithMargin) {
+ // There is enough space at the top of the content rect for the main panel
+ // but not the overflow.
+ // Position above but open downwards.
+ updateOverflowHeight(availableHeightThroughContentDown - margin);
+ y = contentRectOnScreen.top - toolbarHeightWithVerticalMargin;
+ mOpenOverflowUpwards = false;
+ } else if (availableHeightBelowContent >= minimumOverflowHeightWithMargin) {
+ // There is enough space at the bottom of the content rect for the overflow.
+ // Position below and open downwards.
+ updateOverflowHeight(availableHeightBelowContent - margin);
+ y = contentRectOnScreen.bottom;
+ mOpenOverflowUpwards = false;
+ } else if (availableHeightBelowContent >= toolbarHeightWithVerticalMargin
+ && mViewPortOnScreen.height() >= minimumOverflowHeightWithMargin) {
+ // There is enough space at the bottom of the content rect for the main panel
+ // but not the overflow.
+ // Position below but open upwards.
+ updateOverflowHeight(availableHeightThroughContentUp - margin);
+ y = contentRectOnScreen.bottom + toolbarHeightWithVerticalMargin
+ - mPopupWindow.getHeight();
+ mOpenOverflowUpwards = true;
+ } else {
+ // Not enough space.
+ // Position at the top of the view port and open downwards.
+ updateOverflowHeight(mViewPortOnScreen.height() - margin);
+ y = mViewPortOnScreen.top;
+ mOpenOverflowUpwards = false;
+ }
+ }
+
+ // We later specify the location of PopupWindow relative to the attached window.
+ // The idea here is that 1) we can get the location of a View in both window coordinates
+ // and screen coordinates, where the offset between them should be equal to the window
+ // origin, and 2) we can use an arbitrary for this calculation while calculating the
+ // location of the rootview is supposed to be least expensive.
+ // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can avoid
+ // the following calculation.
+ mParent.getRootView().getLocationOnScreen(mTmpCoords);
+ int rootViewLeftOnScreen = mTmpCoords[0];
+ int rootViewTopOnScreen = mTmpCoords[1];
+ mParent.getRootView().getLocationInWindow(mTmpCoords);
+ int rootViewLeftOnWindow = mTmpCoords[0];
+ int rootViewTopOnWindow = mTmpCoords[1];
+ int windowLeftOnScreen = rootViewLeftOnScreen - rootViewLeftOnWindow;
+ int windowTopOnScreen = rootViewTopOnScreen - rootViewTopOnWindow;
+ mCoordsOnWindow.set(
+ Math.max(0, x - windowLeftOnScreen), Math.max(0, y - windowTopOnScreen));
+ }
+
+ /**
+ * Performs the "show" animation on the floating popup.
+ */
+ private void runShowAnimation() {
+ mShowAnimation.start();
+ }
+
+ /**
+ * Performs the "dismiss" animation on the floating popup.
+ */
+ private void runDismissAnimation() {
+ mDismissAnimation.start();
+ }
+
+ /**
+ * Performs the "hide" animation on the floating popup.
+ */
+ private void runHideAnimation() {
+ mHideAnimation.start();
+ }
+
+ private void cancelDismissAndHideAnimations() {
+ mDismissAnimation.cancel();
+ mHideAnimation.cancel();
+ }
+
+ private void cancelOverflowAnimations() {
+ mContentContainer.clearAnimation();
+ mMainPanel.animate().cancel();
+ mOverflowPanel.animate().cancel();
+ mToArrow.stop();
+ mToOverflow.stop();
+ }
+
+ private void openOverflow() {
+ final int targetWidth = mOverflowPanelSize.getWidth();
+ final int targetHeight = mOverflowPanelSize.getHeight();
+ final int startWidth = mContentContainer.getWidth();
+ final int startHeight = mContentContainer.getHeight();
+ final float startY = mContentContainer.getY();
+ final float left = mContentContainer.getX();
+ final float right = left + mContentContainer.getWidth();
+ Animation widthAnimation = new Animation() {
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth));
+ setWidth(mContentContainer, startWidth + deltaWidth);
+ if (isInRTLMode()) {
+ mContentContainer.setX(left);
+
+ // Lock the panels in place.
+ mMainPanel.setX(0);
+ mOverflowPanel.setX(0);
+ } else {
+ mContentContainer.setX(right - mContentContainer.getWidth());
+
+ // Offset the panels' positions so they look like they're locked in place
+ // on the screen.
+ mMainPanel.setX(mContentContainer.getWidth() - startWidth);
+ mOverflowPanel.setX(mContentContainer.getWidth() - targetWidth);
+ }
+ }
+ };
+ Animation heightAnimation = new Animation() {
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ int deltaHeight = (int) (interpolatedTime * (targetHeight - startHeight));
+ setHeight(mContentContainer, startHeight + deltaHeight);
+ if (mOpenOverflowUpwards) {
+ mContentContainer.setY(
+ startY - (mContentContainer.getHeight() - startHeight));
+ positionContentYCoordinatesIfOpeningOverflowUpwards();
+ }
+ }
+ };
+ final float overflowButtonStartX = mOverflowButton.getX();
+ final float overflowButtonTargetX =
+ isInRTLMode() ? overflowButtonStartX + targetWidth - mOverflowButton.getWidth()
+ : overflowButtonStartX - targetWidth + mOverflowButton.getWidth();
+ Animation overflowButtonAnimation = new Animation() {
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ float overflowButtonX = overflowButtonStartX
+ + interpolatedTime * (overflowButtonTargetX - overflowButtonStartX);
+ float deltaContainerWidth =
+ isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth;
+ float actualOverflowButtonX = overflowButtonX + deltaContainerWidth;
+ mOverflowButton.setX(actualOverflowButtonX);
+ }
+ };
+ widthAnimation.setInterpolator(mLogAccelerateInterpolator);
+ widthAnimation.setDuration(getAdjustedDuration(250));
+ heightAnimation.setInterpolator(mFastOutSlowInInterpolator);
+ heightAnimation.setDuration(getAdjustedDuration(250));
+ overflowButtonAnimation.setInterpolator(mFastOutSlowInInterpolator);
+ overflowButtonAnimation.setDuration(getAdjustedDuration(250));
+ mOpenOverflowAnimation.getAnimations().clear();
+ mOpenOverflowAnimation.getAnimations().clear();
+ mOpenOverflowAnimation.addAnimation(widthAnimation);
+ mOpenOverflowAnimation.addAnimation(heightAnimation);
+ mOpenOverflowAnimation.addAnimation(overflowButtonAnimation);
+ mContentContainer.startAnimation(mOpenOverflowAnimation);
+ mIsOverflowOpen = true;
+ mMainPanel.animate()
+ .alpha(0).withLayer()
+ .setInterpolator(mLinearOutSlowInInterpolator)
+ .setDuration(250)
+ .start();
+ mOverflowPanel.setAlpha(1); // fadeIn in 0ms.
+ }
+
+ private void closeOverflow() {
+ final int targetWidth = mMainPanelSize.getWidth();
+ final int startWidth = mContentContainer.getWidth();
+ final float left = mContentContainer.getX();
+ final float right = left + mContentContainer.getWidth();
+ Animation widthAnimation = new Animation() {
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth));
+ setWidth(mContentContainer, startWidth + deltaWidth);
+ if (isInRTLMode()) {
+ mContentContainer.setX(left);
+
+ // Lock the panels in place.
+ mMainPanel.setX(0);
+ mOverflowPanel.setX(0);
+ } else {
+ mContentContainer.setX(right - mContentContainer.getWidth());
+
+ // Offset the panels' positions so they look like they're locked in place
+ // on the screen.
+ mMainPanel.setX(mContentContainer.getWidth() - targetWidth);
+ mOverflowPanel.setX(mContentContainer.getWidth() - startWidth);
+ }
+ }
+ };
+ final int targetHeight = mMainPanelSize.getHeight();
+ final int startHeight = mContentContainer.getHeight();
+ final float bottom = mContentContainer.getY() + mContentContainer.getHeight();
+ Animation heightAnimation = new Animation() {
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ int deltaHeight = (int) (interpolatedTime * (targetHeight - startHeight));
+ setHeight(mContentContainer, startHeight + deltaHeight);
+ if (mOpenOverflowUpwards) {
+ mContentContainer.setY(bottom - mContentContainer.getHeight());
+ positionContentYCoordinatesIfOpeningOverflowUpwards();
+ }
+ }
+ };
+ final float overflowButtonStartX = mOverflowButton.getX();
+ final float overflowButtonTargetX =
+ isInRTLMode() ? overflowButtonStartX - startWidth + mOverflowButton.getWidth()
+ : overflowButtonStartX + startWidth - mOverflowButton.getWidth();
+ Animation overflowButtonAnimation = new Animation() {
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ float overflowButtonX = overflowButtonStartX
+ + interpolatedTime * (overflowButtonTargetX - overflowButtonStartX);
+ float deltaContainerWidth =
+ isInRTLMode() ? 0 : mContentContainer.getWidth() - startWidth;
+ float actualOverflowButtonX = overflowButtonX + deltaContainerWidth;
+ mOverflowButton.setX(actualOverflowButtonX);
+ }
+ };
+ widthAnimation.setInterpolator(mFastOutSlowInInterpolator);
+ widthAnimation.setDuration(getAdjustedDuration(250));
+ heightAnimation.setInterpolator(mLogAccelerateInterpolator);
+ heightAnimation.setDuration(getAdjustedDuration(250));
+ overflowButtonAnimation.setInterpolator(mFastOutSlowInInterpolator);
+ overflowButtonAnimation.setDuration(getAdjustedDuration(250));
+ mCloseOverflowAnimation.getAnimations().clear();
+ mCloseOverflowAnimation.addAnimation(widthAnimation);
+ mCloseOverflowAnimation.addAnimation(heightAnimation);
+ mCloseOverflowAnimation.addAnimation(overflowButtonAnimation);
+ mContentContainer.startAnimation(mCloseOverflowAnimation);
+ mIsOverflowOpen = false;
+ mMainPanel.animate()
+ .alpha(1).withLayer()
+ .setInterpolator(mFastOutLinearInInterpolator)
+ .setDuration(100)
+ .start();
+ mOverflowPanel.animate()
+ .alpha(0).withLayer()
+ .setInterpolator(mLinearOutSlowInInterpolator)
+ .setDuration(150)
+ .start();
+ }
+
+ /**
+ * Defines the position of the floating toolbar popup panels when transition animation has
+ * stopped.
+ */
+ private void setPanelsStatesAtRestingPosition() {
+ mOverflowButton.setEnabled(true);
+ mOverflowPanel.awakenScrollBars();
+
+ if (mIsOverflowOpen) {
+ // Set open state.
+ final Size containerSize = mOverflowPanelSize;
+ setSize(mContentContainer, containerSize);
+ mMainPanel.setAlpha(0);
+ mMainPanel.setVisibility(View.INVISIBLE);
+ mOverflowPanel.setAlpha(1);
+ mOverflowPanel.setVisibility(View.VISIBLE);
+ mOverflowButton.setImageDrawable(mArrow);
+ mOverflowButton.setContentDescription(mContext.getString(
+ R.string.floating_toolbar_close_overflow_description));
+
+ // Update x-coordinates depending on RTL state.
+ if (isInRTLMode()) {
+ mContentContainer.setX(mMarginHorizontal); // align left
+ mMainPanel.setX(0); // align left
+ mOverflowButton.setX(// align right
+ containerSize.getWidth() - mOverflowButtonSize.getWidth());
+ mOverflowPanel.setX(0); // align left
+ } else {
+ mContentContainer.setX(// align right
+ mPopupWindow.getWidth() - containerSize.getWidth() - mMarginHorizontal);
+ mMainPanel.setX(-mContentContainer.getX()); // align right
+ mOverflowButton.setX(0); // align left
+ mOverflowPanel.setX(0); // align left
+ }
+
+ // Update y-coordinates depending on overflow's open direction.
+ if (mOpenOverflowUpwards) {
+ mContentContainer.setY(mMarginVertical); // align top
+ mMainPanel.setY(// align bottom
+ containerSize.getHeight() - mContentContainer.getHeight());
+ mOverflowButton.setY(// align bottom
+ containerSize.getHeight() - mOverflowButtonSize.getHeight());
+ mOverflowPanel.setY(0); // align top
+ } else {
+ // opens downwards.
+ mContentContainer.setY(mMarginVertical); // align top
+ mMainPanel.setY(0); // align top
+ mOverflowButton.setY(0); // align top
+ mOverflowPanel.setY(mOverflowButtonSize.getHeight()); // align bottom
+ }
+ } else {
+ // Overflow not open. Set closed state.
+ final Size containerSize = mMainPanelSize;
+ setSize(mContentContainer, containerSize);
+ mMainPanel.setAlpha(1);
+ mMainPanel.setVisibility(View.VISIBLE);
+ mOverflowPanel.setAlpha(0);
+ mOverflowPanel.setVisibility(View.INVISIBLE);
+ mOverflowButton.setImageDrawable(mOverflow);
+ mOverflowButton.setContentDescription(mContext.getString(
+ R.string.floating_toolbar_open_overflow_description));
+
+ if (hasOverflow()) {
+ // Update x-coordinates depending on RTL state.
+ if (isInRTLMode()) {
+ mContentContainer.setX(mMarginHorizontal); // align left
+ mMainPanel.setX(0); // align left
+ mOverflowButton.setX(0); // align left
+ mOverflowPanel.setX(0); // align left
+ } else {
+ mContentContainer.setX(// align right
+ mPopupWindow.getWidth() - containerSize.getWidth() - mMarginHorizontal);
+ mMainPanel.setX(0); // align left
+ mOverflowButton.setX(// align right
+ containerSize.getWidth() - mOverflowButtonSize.getWidth());
+ mOverflowPanel.setX(// align right
+ containerSize.getWidth() - mOverflowPanelSize.getWidth());
+ }
+
+ // Update y-coordinates depending on overflow's open direction.
+ if (mOpenOverflowUpwards) {
+ mContentContainer.setY(// align bottom
+ mMarginVertical + mOverflowPanelSize.getHeight()
+ - containerSize.getHeight());
+ mMainPanel.setY(0); // align top
+ mOverflowButton.setY(0); // align top
+ mOverflowPanel.setY(// align bottom
+ containerSize.getHeight() - mOverflowPanelSize.getHeight());
+ } else {
+ // opens downwards.
+ mContentContainer.setY(mMarginVertical); // align top
+ mMainPanel.setY(0); // align top
+ mOverflowButton.setY(0); // align top
+ mOverflowPanel.setY(mOverflowButtonSize.getHeight()); // align bottom
+ }
+ } else {
+ // No overflow.
+ mContentContainer.setX(mMarginHorizontal); // align left
+ mContentContainer.setY(mMarginVertical); // align top
+ mMainPanel.setX(0); // align left
+ mMainPanel.setY(0); // align top
+ }
+ }
+ }
+
+ private void updateOverflowHeight(int suggestedHeight) {
+ if (hasOverflow()) {
+ final int maxItemSize =
+ (suggestedHeight - mOverflowButtonSize.getHeight()) / mLineHeight;
+ final int newHeight = calculateOverflowHeight(maxItemSize);
+ if (mOverflowPanelSize.getHeight() != newHeight) {
+ mOverflowPanelSize = new Size(mOverflowPanelSize.getWidth(), newHeight);
+ }
+ setSize(mOverflowPanel, mOverflowPanelSize);
+ if (mIsOverflowOpen) {
+ setSize(mContentContainer, mOverflowPanelSize);
+ if (mOpenOverflowUpwards) {
+ final int deltaHeight = mOverflowPanelSize.getHeight() - newHeight;
+ mContentContainer.setY(mContentContainer.getY() + deltaHeight);
+ mOverflowButton.setY(mOverflowButton.getY() - deltaHeight);
+ }
+ } else {
+ setSize(mContentContainer, mMainPanelSize);
+ }
+ updatePopupSize();
+ }
+ }
+
+ private void updatePopupSize() {
+ int width = 0;
+ int height = 0;
+ if (mMainPanelSize != null) {
+ width = Math.max(width, mMainPanelSize.getWidth());
+ height = Math.max(height, mMainPanelSize.getHeight());
+ }
+ if (mOverflowPanelSize != null) {
+ width = Math.max(width, mOverflowPanelSize.getWidth());
+ height = Math.max(height, mOverflowPanelSize.getHeight());
+ }
+ mPopupWindow.setWidth(width + mMarginHorizontal * 2);
+ mPopupWindow.setHeight(height + mMarginVertical * 2);
+ maybeComputeTransitionDurationScale();
+ }
+
+ private void refreshViewPort() {
+ mParent.getWindowVisibleDisplayFrame(mViewPortOnScreen);
+ }
+
+ private int getAdjustedToolbarWidth(int suggestedWidth) {
+ int width = suggestedWidth;
+ refreshViewPort();
+ int maximumWidth = mViewPortOnScreen.width() - 2 * mParent.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
+ if (width <= 0) {
+ width = mParent.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width);
+ }
+ return Math.min(width, maximumWidth);
+ }
+
+ /**
+ * Sets the touchable region of this popup to be zero. This means that all touch events on
+ * this popup will go through to the surface behind it.
+ */
+ private void setZeroTouchableSurface() {
+ mTouchableRegion.setEmpty();
+ }
+
+ /**
+ * Sets the touchable region of this popup to be the area occupied by its content.
+ */
+ private void setContentAreaAsTouchableSurface() {
+ Objects.requireNonNull(mMainPanelSize);
+ final int width;
+ final int height;
+ if (mIsOverflowOpen) {
+ Objects.requireNonNull(mOverflowPanelSize);
+ width = mOverflowPanelSize.getWidth();
+ height = mOverflowPanelSize.getHeight();
+ } else {
+ width = mMainPanelSize.getWidth();
+ height = mMainPanelSize.getHeight();
+ }
+ mTouchableRegion.set(
+ (int) mContentContainer.getX(),
+ (int) mContentContainer.getY(),
+ (int) mContentContainer.getX() + width,
+ (int) mContentContainer.getY() + height);
+ }
+
+ /**
+ * Make the touchable area of this popup be the area specified by mTouchableRegion.
+ * This should be called after the popup window has been dismissed (dismiss/hide)
+ * and is probably being re-shown with a new content root view.
+ */
+ private void setTouchableSurfaceInsetsComputer() {
+ ViewTreeObserver viewTreeObserver = mPopupWindow.getContentView()
+ .getRootView()
+ .getViewTreeObserver();
+ viewTreeObserver.removeOnComputeInternalInsetsListener(mInsetsComputer);
+ viewTreeObserver.addOnComputeInternalInsetsListener(mInsetsComputer);
+ }
+
+ private boolean isInRTLMode() {
+ return mContext.getApplicationInfo().hasRtlSupport()
+ && mContext.getResources().getConfiguration().getLayoutDirection()
+ == View.LAYOUT_DIRECTION_RTL;
+ }
+
+ private boolean hasOverflow() {
+ return mOverflowPanelSize != null;
+ }
+
+ /**
+ * Fits as many menu items in the main panel and returns a list of the menu items that
+ * were not fit in.
+ *
+ * @return The menu items that are not included in this main panel.
+ */
+ public List<MenuItem> layoutMainPanelItems(
+ List<MenuItem> menuItems, final int toolbarWidth) {
+ Objects.requireNonNull(menuItems);
+
+ int availableWidth = toolbarWidth;
+
+ final LinkedList<MenuItem> remainingMenuItems = new LinkedList<>();
+ // add the overflow menu items to the end of the remainingMenuItems list.
+ final LinkedList<MenuItem> overflowMenuItems = new LinkedList();
+ for (MenuItem menuItem : menuItems) {
+ if (menuItem.getItemId() != android.R.id.textAssist
+ && menuItem.requiresOverflow()) {
+ overflowMenuItems.add(menuItem);
+ } else {
+ remainingMenuItems.add(menuItem);
+ }
+ }
+ remainingMenuItems.addAll(overflowMenuItems);
+
+ mMainPanel.removeAllViews();
+ mMainPanel.setPaddingRelative(0, 0, 0, 0);
+
+ int lastGroupId = -1;
+ boolean isFirstItem = true;
+ while (!remainingMenuItems.isEmpty()) {
+ final MenuItem menuItem = remainingMenuItems.peek();
+
+ // if this is the first item, regardless of requiresOverflow(), it should be
+ // displayed on the main panel. Otherwise all items including this one will be
+ // overflow items, and should be displayed in overflow panel.
+ if (!isFirstItem && menuItem.requiresOverflow()) {
+ break;
+ }
+
+ final boolean showIcon = isFirstItem && menuItem.getItemId() == R.id.textAssist;
+ final View menuItemButton = createMenuItemButton(
+ mContext, menuItem, mIconTextSpacing, showIcon);
+ if (!showIcon && menuItemButton instanceof LinearLayout) {
+ ((LinearLayout) menuItemButton).setGravity(Gravity.CENTER);
+ }
+
+ // Adding additional start padding for the first button to even out button spacing.
+ if (isFirstItem) {
+ menuItemButton.setPaddingRelative(
+ (int) (1.5 * menuItemButton.getPaddingStart()),
+ menuItemButton.getPaddingTop(),
+ menuItemButton.getPaddingEnd(),
+ menuItemButton.getPaddingBottom());
+ }
+
+ // Adding additional end padding for the last button to even out button spacing.
+ boolean isLastItem = remainingMenuItems.size() == 1;
+ if (isLastItem) {
+ menuItemButton.setPaddingRelative(
+ menuItemButton.getPaddingStart(),
+ menuItemButton.getPaddingTop(),
+ (int) (1.5 * menuItemButton.getPaddingEnd()),
+ menuItemButton.getPaddingBottom());
+ }
+
+ menuItemButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ final int menuItemButtonWidth = Math.min(
+ menuItemButton.getMeasuredWidth(), toolbarWidth);
+
+ // Check if we can fit an item while reserving space for the overflowButton.
+ final boolean canFitWithOverflow =
+ menuItemButtonWidth <= availableWidth - mOverflowButtonSize.getWidth();
+ final boolean canFitNoOverflow =
+ isLastItem && menuItemButtonWidth <= availableWidth;
+ if (canFitWithOverflow || canFitNoOverflow) {
+ setButtonTagAndClickListener(menuItemButton, menuItem);
+ // Set tooltips for main panel items, but not overflow items (b/35726766).
+ menuItemButton.setTooltipText(menuItem.getTooltipText());
+ mMainPanel.addView(menuItemButton);
+ final ViewGroup.LayoutParams params = menuItemButton.getLayoutParams();
+ params.width = menuItemButtonWidth;
+ menuItemButton.setLayoutParams(params);
+ availableWidth -= menuItemButtonWidth;
+ remainingMenuItems.pop();
+ } else {
+ break;
+ }
+ lastGroupId = menuItem.getGroupId();
+ isFirstItem = false;
+ }
+
+ if (!remainingMenuItems.isEmpty()) {
+ // Reserve space for overflowButton.
+ mMainPanel.setPaddingRelative(0, 0, mOverflowButtonSize.getWidth(), 0);
+ }
+
+ mMainPanelSize = measure(mMainPanel);
+ return remainingMenuItems;
+ }
+
+ private void layoutOverflowPanelItems(List<MenuItem> menuItems) {
+ ArrayAdapter<MenuItem> overflowPanelAdapter =
+ (ArrayAdapter<MenuItem>) mOverflowPanel.getAdapter();
+ overflowPanelAdapter.clear();
+ final int size = menuItems.size();
+ for (int i = 0; i < size; i++) {
+ overflowPanelAdapter.add(menuItems.get(i));
+ }
+ mOverflowPanel.setAdapter(overflowPanelAdapter);
+ if (mOpenOverflowUpwards) {
+ mOverflowPanel.setY(0);
+ } else {
+ mOverflowPanel.setY(mOverflowButtonSize.getHeight());
+ }
+
+ int width = Math.max(getOverflowWidth(), mOverflowButtonSize.getWidth());
+ int height = calculateOverflowHeight(MAX_OVERFLOW_SIZE);
+ mOverflowPanelSize = new Size(width, height);
+ setSize(mOverflowPanel, mOverflowPanelSize);
+ }
+
+ /**
+ * Resets the content container and appropriately position it's panels.
+ */
+ private void preparePopupContent() {
+ mContentContainer.removeAllViews();
+
+ // Add views in the specified order so they stack up as expected.
+ // Order: overflowPanel, mainPanel, overflowButton.
+ if (hasOverflow()) {
+ mContentContainer.addView(mOverflowPanel);
+ }
+ mContentContainer.addView(mMainPanel);
+ if (hasOverflow()) {
+ mContentContainer.addView(mOverflowButton);
+ }
+ setPanelsStatesAtRestingPosition();
+ setContentAreaAsTouchableSurface();
+
+ // The positioning of contents in RTL is wrong when the view is first rendered.
+ // Hide the view and post a runnable to recalculate positions and render the view.
+ // TODO: Investigate why this happens and fix.
+ if (isInRTLMode()) {
+ mContentContainer.setAlpha(0);
+ mContentContainer.post(mPreparePopupContentRTLHelper);
+ }
+ }
+
+ /**
+ * Clears out the panels and their container. Resets their calculated sizes.
+ */
+ private void clearPanels() {
+ mOverflowPanelSize = null;
+ mMainPanelSize = null;
+ mIsOverflowOpen = false;
+ mMainPanel.removeAllViews();
+ ArrayAdapter<MenuItem> overflowPanelAdapter =
+ (ArrayAdapter<MenuItem>) mOverflowPanel.getAdapter();
+ overflowPanelAdapter.clear();
+ mOverflowPanel.setAdapter(overflowPanelAdapter);
+ mContentContainer.removeAllViews();
+ }
+
+ private void positionContentYCoordinatesIfOpeningOverflowUpwards() {
+ if (mOpenOverflowUpwards) {
+ mMainPanel.setY(mContentContainer.getHeight() - mMainPanelSize.getHeight());
+ mOverflowButton.setY(mContentContainer.getHeight() - mOverflowButton.getHeight());
+ mOverflowPanel.setY(mContentContainer.getHeight() - mOverflowPanelSize.getHeight());
+ }
+ }
+
+ private int getOverflowWidth() {
+ int overflowWidth = 0;
+ final int count = mOverflowPanel.getAdapter().getCount();
+ for (int i = 0; i < count; i++) {
+ MenuItem menuItem = (MenuItem) mOverflowPanel.getAdapter().getItem(i);
+ overflowWidth =
+ Math.max(mOverflowPanelViewHelper.calculateWidth(menuItem), overflowWidth);
+ }
+ return overflowWidth;
+ }
+
+ private int calculateOverflowHeight(int maxItemSize) {
+ // Maximum of 4 items, minimum of 2 if the overflow has to scroll.
+ int actualSize = Math.min(
+ MAX_OVERFLOW_SIZE,
+ Math.min(
+ Math.max(MIN_OVERFLOW_SIZE, maxItemSize),
+ mOverflowPanel.getCount()));
+ int extension = 0;
+ if (actualSize < mOverflowPanel.getCount()) {
+ // The overflow will require scrolling to get to all the items.
+ // Extend the height so that part of the hidden items is displayed.
+ extension = (int) (mLineHeight * 0.5f);
+ }
+ return actualSize * mLineHeight
+ + mOverflowButtonSize.getHeight()
+ + extension;
+ }
+
+ private void setButtonTagAndClickListener(View menuItemButton, MenuItem menuItem) {
+ menuItemButton.setTag(MenuItemRepr.of(menuItem));
+ menuItemButton.setOnClickListener(mMenuItemButtonOnClickListener);
+ }
+
+ /**
+ * NOTE: Use only in android.view.animation.* animations. Do not use in android.animation.*
+ * animations. See comment about this in the code.
+ */
+ private int getAdjustedDuration(int originalDuration) {
+ if (mTransitionDurationScale < 150) {
+ // For smaller transition, decrease the time.
+ return Math.max(originalDuration - 50, 0);
+ } else if (mTransitionDurationScale > 300) {
+ // For bigger transition, increase the time.
+ return originalDuration + 50;
+ }
+
+ // Scale the animation duration with getDurationScale(). This allows
+ // android.view.animation.* animations to scale just like android.animation.* animations
+ // when animator duration scale is adjusted in "Developer Options".
+ // For this reason, do not use this method for android.animation.* animations.
+ return (int) (originalDuration * ValueAnimator.getDurationScale());
+ }
+
+ private void maybeComputeTransitionDurationScale() {
+ if (mMainPanelSize != null && mOverflowPanelSize != null) {
+ int w = mMainPanelSize.getWidth() - mOverflowPanelSize.getWidth();
+ int h = mOverflowPanelSize.getHeight() - mMainPanelSize.getHeight();
+ mTransitionDurationScale = (int) (Math.sqrt(w * w + h * h)
+ / mContentContainer.getContext().getResources().getDisplayMetrics().density);
+ }
+ }
+
+ private ViewGroup createMainPanel() {
+ ViewGroup mainPanel = new LinearLayout(mContext) {
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (isOverflowAnimating()) {
+ // Update widthMeasureSpec to make sure that this view is not clipped
+ // as we offset its coordinates with respect to its parent.
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ mMainPanelSize.getWidth(),
+ MeasureSpec.EXACTLY);
+ }
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ // Intercept the touch event while the overflow is animating.
+ return isOverflowAnimating();
+ }
+ };
+ return mainPanel;
+ }
+
+ private ImageButton createOverflowButton() {
+ final ImageButton overflowButton = (ImageButton) LayoutInflater.from(mContext)
+ .inflate(R.layout.floating_popup_overflow_button, null);
+ overflowButton.setImageDrawable(mOverflow);
+ overflowButton.setOnClickListener(v -> {
+ if (mIsOverflowOpen) {
+ overflowButton.setImageDrawable(mToOverflow);
+ mToOverflow.start();
+ closeOverflow();
+ } else {
+ overflowButton.setImageDrawable(mToArrow);
+ mToArrow.start();
+ openOverflow();
+ }
+ });
+ return overflowButton;
+ }
+
+ private FloatingToolbarPopup.OverflowPanel createOverflowPanel() {
+ final FloatingToolbarPopup.OverflowPanel
+ overflowPanel = new FloatingToolbarPopup.OverflowPanel(this);
+ overflowPanel.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ overflowPanel.setDivider(null);
+ overflowPanel.setDividerHeight(0);
+
+ final ArrayAdapter adapter =
+ new ArrayAdapter<MenuItem>(mContext, 0) {
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return mOverflowPanelViewHelper.getView(
+ getItem(position), mOverflowPanelSize.getWidth(), convertView);
+ }
+ };
+ overflowPanel.setAdapter(adapter);
+
+ overflowPanel.setOnItemClickListener((parent, view, position, id) -> {
+ MenuItem menuItem = (MenuItem) overflowPanel.getAdapter().getItem(position);
+ if (mOnMenuItemClickListener != null) {
+ mOnMenuItemClickListener.onMenuItemClick(menuItem);
+ }
+ });
+
+ return overflowPanel;
+ }
+
+ private boolean isOverflowAnimating() {
+ final boolean overflowOpening = mOpenOverflowAnimation.hasStarted()
+ && !mOpenOverflowAnimation.hasEnded();
+ final boolean overflowClosing = mCloseOverflowAnimation.hasStarted()
+ && !mCloseOverflowAnimation.hasEnded();
+ return overflowOpening || overflowClosing;
+ }
+
+ private Animation.AnimationListener createOverflowAnimationListener() {
+ Animation.AnimationListener listener = new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+ // Disable the overflow button while it's animating.
+ // It will be re-enabled when the animation stops.
+ mOverflowButton.setEnabled(false);
+ // Ensure both panels have visibility turned on when the overflow animation
+ // starts.
+ mMainPanel.setVisibility(View.VISIBLE);
+ mOverflowPanel.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ // Posting this because it seems like this is called before the animation
+ // actually ends.
+ mContentContainer.post(() -> {
+ setPanelsStatesAtRestingPosition();
+ setContentAreaAsTouchableSurface();
+ });
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+ }
+ };
+ return listener;
+ }
+
+ private static Size measure(View view) {
+ Preconditions.checkState(view.getParent() == null);
+ view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ return new Size(view.getMeasuredWidth(), view.getMeasuredHeight());
+ }
+
+ private static void setSize(View view, int width, int height) {
+ view.setMinimumWidth(width);
+ view.setMinimumHeight(height);
+ ViewGroup.LayoutParams params = view.getLayoutParams();
+ params = (params == null) ? new ViewGroup.LayoutParams(0, 0) : params;
+ params.width = width;
+ params.height = height;
+ view.setLayoutParams(params);
+ }
+
+ private static void setSize(View view, Size size) {
+ setSize(view, size.getWidth(), size.getHeight());
+ }
+
+ private static void setWidth(View view, int width) {
+ ViewGroup.LayoutParams params = view.getLayoutParams();
+ setSize(view, width, params.height);
+ }
+
+ private static void setHeight(View view, int height) {
+ ViewGroup.LayoutParams params = view.getLayoutParams();
+ setSize(view, params.width, height);
+ }
+
+ /**
+ * A custom ListView for the overflow panel.
+ */
+ private static final class OverflowPanel extends ListView {
+
+ private final FloatingToolbarPopup mPopup;
+
+ OverflowPanel(FloatingToolbarPopup popup) {
+ super(Objects.requireNonNull(popup).mContext);
+ this.mPopup = popup;
+ setScrollBarDefaultDelayBeforeFade(ViewConfiguration.getScrollDefaultDelay() * 3);
+ setScrollIndicators(View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // Update heightMeasureSpec to make sure that this view is not clipped
+ // as we offset it's coordinates with respect to its parent.
+ int height = mPopup.mOverflowPanelSize.getHeight()
+ - mPopup.mOverflowButtonSize.getHeight();
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (mPopup.isOverflowAnimating()) {
+ // Eat the touch event.
+ return true;
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+
+ @Override
+ protected boolean awakenScrollBars() {
+ return super.awakenScrollBars();
+ }
+ }
+
+ /**
+ * A custom interpolator used for various floating toolbar animations.
+ */
+ private static final class LogAccelerateInterpolator implements Interpolator {
+
+ private static final int BASE = 100;
+ private static final float LOGS_SCALE = 1f / computeLog(1, BASE);
+
+ private static float computeLog(float t, int base) {
+ return (float) (1 - Math.pow(base, -t));
+ }
+
+ @Override
+ public float getInterpolation(float t) {
+ return 1 - computeLog(1 - t, BASE) * LOGS_SCALE;
+ }
+ }
+
+ /**
+ * A helper for generating views for the overflow panel.
+ */
+ private static final class OverflowPanelViewHelper {
+
+ private final View mCalculator;
+ private final int mIconTextSpacing;
+ private final int mSidePadding;
+
+ private final Context mContext;
+
+ OverflowPanelViewHelper(Context context, int iconTextSpacing) {
+ mContext = Objects.requireNonNull(context);
+ mIconTextSpacing = iconTextSpacing;
+ mSidePadding = context.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_overflow_side_padding);
+ mCalculator = createMenuButton(null);
+ }
+
+ public View getView(MenuItem menuItem, int minimumWidth, View convertView) {
+ Objects.requireNonNull(menuItem);
+ if (convertView != null) {
+ updateMenuItemButton(
+ convertView, menuItem, mIconTextSpacing, shouldShowIcon(menuItem));
+ } else {
+ convertView = createMenuButton(menuItem);
+ }
+ convertView.setMinimumWidth(minimumWidth);
+ return convertView;
+ }
+
+ public int calculateWidth(MenuItem menuItem) {
+ updateMenuItemButton(
+ mCalculator, menuItem, mIconTextSpacing, shouldShowIcon(menuItem));
+ mCalculator.measure(
+ View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ return mCalculator.getMeasuredWidth();
+ }
+
+ private View createMenuButton(MenuItem menuItem) {
+ View button = createMenuItemButton(
+ mContext, menuItem, mIconTextSpacing, shouldShowIcon(menuItem));
+ button.setPadding(mSidePadding, 0, mSidePadding, 0);
+ return button;
+ }
+
+ private boolean shouldShowIcon(MenuItem menuItem) {
+ if (menuItem != null) {
+ return menuItem.getGroupId() == android.R.id.textAssist;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Creates and returns a menu button for the specified menu item.
+ */
+ private static View createMenuItemButton(
+ Context context, MenuItem menuItem, int iconTextSpacing, boolean showIcon) {
+ final View menuItemButton = LayoutInflater.from(context)
+ .inflate(R.layout.floating_popup_menu_button, null);
+ if (menuItem != null) {
+ updateMenuItemButton(menuItemButton, menuItem, iconTextSpacing, showIcon);
+ }
+ return menuItemButton;
+ }
+
+ /**
+ * Updates the specified menu item button with the specified menu item data.
+ */
+ private static void updateMenuItemButton(
+ View menuItemButton, MenuItem menuItem, int iconTextSpacing, boolean showIcon) {
+ final TextView buttonText = menuItemButton.findViewById(
+ R.id.floating_toolbar_menu_item_text);
+ buttonText.setEllipsize(null);
+ if (TextUtils.isEmpty(menuItem.getTitle())) {
+ buttonText.setVisibility(View.GONE);
+ } else {
+ buttonText.setVisibility(View.VISIBLE);
+ buttonText.setText(menuItem.getTitle());
+ }
+ final ImageView buttonIcon = menuItemButton.findViewById(
+ R.id.floating_toolbar_menu_item_image);
+ if (menuItem.getIcon() == null || !showIcon) {
+ buttonIcon.setVisibility(View.GONE);
+ if (buttonText != null) {
+ buttonText.setPaddingRelative(0, 0, 0, 0);
+ }
+ } else {
+ buttonIcon.setVisibility(View.VISIBLE);
+ buttonIcon.setImageDrawable(menuItem.getIcon());
+ if (buttonText != null) {
+ buttonText.setPaddingRelative(iconTextSpacing, 0, 0, 0);
+ }
+ }
+ final CharSequence contentDescription = menuItem.getContentDescription();
+ if (TextUtils.isEmpty(contentDescription)) {
+ menuItemButton.setContentDescription(menuItem.getTitle());
+ } else {
+ menuItemButton.setContentDescription(contentDescription);
+ }
+ }
+
+ private static ViewGroup createContentContainer(Context context) {
+ ViewGroup contentContainer = (ViewGroup) LayoutInflater.from(context)
+ .inflate(R.layout.floating_popup_container, null);
+ contentContainer.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ contentContainer.setTag(FloatingToolbar.FLOATING_TOOLBAR_TAG);
+ contentContainer.setClipToOutline(true);
+ return contentContainer;
+ }
+
+ private static PopupWindow createPopupWindow(ViewGroup content) {
+ ViewGroup popupContentHolder = new LinearLayout(content.getContext());
+ PopupWindow popupWindow = new PopupWindow(popupContentHolder);
+ // TODO: Use .setIsLaidOutInScreen(true) instead of .setClippingEnabled(false)
+ // unless FLAG_LAYOUT_IN_SCREEN has any unintentional side-effects.
+ popupWindow.setClippingEnabled(false);
+ popupWindow.setWindowLayoutType(
+ WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
+ popupWindow.setAnimationStyle(0);
+ popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ content.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ popupContentHolder.addView(content);
+ return popupWindow;
+ }
+
+ /**
+ * Creates an "appear" animation for the specified view.
+ *
+ * @param view The view to animate
+ */
+ private static AnimatorSet createEnterAnimation(View view) {
+ AnimatorSet animation = new AnimatorSet();
+ animation.playTogether(
+ ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(150));
+ return animation;
+ }
+
+ /**
+ * Creates a "disappear" animation for the specified view.
+ *
+ * @param view The view to animate
+ * @param startDelay The start delay of the animation
+ * @param listener The animation listener
+ */
+ private static AnimatorSet createExitAnimation(
+ View view, int startDelay, Animator.AnimatorListener listener) {
+ AnimatorSet animation = new AnimatorSet();
+ animation.playTogether(
+ ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0).setDuration(100));
+ animation.setStartDelay(startDelay);
+ animation.addListener(listener);
+ return animation;
+ }
+
+ /**
+ * Returns a re-themed context with controlled look and feel for views.
+ */
+ private static Context applyDefaultTheme(Context originalContext) {
+ TypedArray a = originalContext.obtainStyledAttributes(new int[]{R.attr.isLightTheme});
+ boolean isLightTheme = a.getBoolean(0, true);
+ int themeId =
+ isLightTheme ? R.style.Theme_DeviceDefault_Light : R.style.Theme_DeviceDefault;
+ a.recycle();
+ return new ContextThemeWrapper(originalContext, themeId);
+ }
+
+ /**
+ * Represents the identity of a MenuItem that is rendered in a FloatingToolbarPopup.
+ */
+ @VisibleForTesting
+ public static final class MenuItemRepr {
+
+ public final int itemId;
+ public final int groupId;
+ @Nullable public final String title;
+ @Nullable private final Drawable mIcon;
+
+ private MenuItemRepr(
+ int itemId, int groupId, @Nullable CharSequence title, @Nullable Drawable icon) {
+ this.itemId = itemId;
+ this.groupId = groupId;
+ this.title = (title == null) ? null : title.toString();
+ mIcon = icon;
+ }
+
+ /**
+ * Creates an instance of MenuItemRepr for the specified menu item.
+ */
+ public static MenuItemRepr of(MenuItem menuItem) {
+ return new MenuItemRepr(
+ menuItem.getItemId(),
+ menuItem.getGroupId(),
+ menuItem.getTitle(),
+ menuItem.getIcon());
+ }
+
+ /**
+ * Returns this object's hashcode.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(itemId, groupId, title, mIcon);
+ }
+
+ /**
+ * Returns true if this object is the same as the specified object.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof MenuItemRepr)) {
+ return false;
+ }
+ final MenuItemRepr other = (MenuItemRepr) o;
+ return itemId == other.itemId
+ && groupId == other.groupId
+ && TextUtils.equals(title, other.title)
+ // Many Drawables (icons) do not implement equals(). Using equals() here instead
+ // of reference comparisons in case a Drawable subclass implements equals().
+ && Objects.equals(mIcon, other.mIcon);
+ }
+
+ /**
+ * Returns true if the two menu item collections are the same based on MenuItemRepr.
+ */
+ public static boolean reprEquals(
+ Collection<MenuItem> menuItems1, Collection<MenuItem> menuItems2) {
+ if (menuItems1.size() != menuItems2.size()) {
+ return false;
+ }
+
+ final Iterator<MenuItem> menuItems2Iter = menuItems2.iterator();
+ for (MenuItem menuItem1 : menuItems1) {
+ final MenuItem menuItem2 = menuItems2Iter.next();
+ if (!MenuItemRepr.of(menuItem1).equals(MenuItemRepr.of(menuItem2))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 0d33807..be9aaaf 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -641,7 +641,7 @@
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
bool result;
- status_t err = parcel->hasFileDescriptorsInRange(offset, length, result);
+ status_t err = parcel->hasFileDescriptorsInRange(offset, length, &result);
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
return JNI_FALSE;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index bc6a090..40e3f60 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -366,6 +366,7 @@
optional bool translucent = 30;
optional bool pip_auto_enter_enabled = 31;
optional bool in_size_compat_mode = 32;
+ optional float min_aspect_ratio = 33;
}
/* represents WindowToken */
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b4fa652..329f02a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -256,6 +256,9 @@
android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_CONF_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_GROUP_NODE_STATUS_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_GROUP_STATUS_CHANGED" />
<protected-broadcast
android:name="android.bluetooth.action.TETHERING_STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED" />
diff --git a/core/res/OWNERS b/core/res/OWNERS
index 684202b..165dcad 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -28,3 +28,6 @@
# Multiuser
per-file res/xml/config_user_types.xml = file:/MULTIUSER_OWNERS
+
+# Car
+per-file res/values/dimens_car.xml = file:/platform/packages/services/Car:/OWNERS
\ No newline at end of file
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 76f4915..c592ef4 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Laat die program toe om op Bluetooth-toestelle in die omtrek te adverteer"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"bepaal relatiewe posisie tussen ultrabreëbandtoestelle in die omtrek"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Laat die program toe om relatiewe posisie tussen ultrabreëbandtoestelle in die omtrek te bepaal"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interaksie met wi‑fi-toestelle in die omtrek te hê"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Laat die program toe om op toestelle in die omtrek te adverteer, aan hulle te koppel en hul relatiewe posisie te bepaal"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Voorkeur-NFC-betalingdiensinligting"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Laat die program toe om voorkeur-NFC-betalingdiensinligting soos geregistreerde hulpmiddels en roetebestemming te kry."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"beheer kortveldkommunikasie"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Laat die program toe om Moenie Steur Nie-opstelling te lees en skryf."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"begin kyk van toestemminggebruik"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Laat die houer toe om die toestemminggebruik vir \'n program te begin. Behoort nooit vir normale programme nodig te wees nie."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"begin Bekyk Programkenmerke"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Laat die houer toe om die kenmerke-inligting vir \'n program te begin bekyk."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"kry toegang tot sensordata teen \'n hoë monsternemingkoers"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Laat die program toe om monsters van sensordata teen \'n hoër koers as 200 Hz te neem"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Stel wagwoordreëls"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 21c21a9..74fcfc6 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"በአቅራቢያ ላሉ የብሉቱዝ መሣሪያዎችን እንዲያስተዋውቅ መተግበሪያው ያስችለዋል"</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">"በአቅራቢያ ካሉ የWi‑Fi መሣሪያዎች ጋር መስተጋብር መፍጠር"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"መተግበሪያው በአቅራቢያ ያሉ የWi-Fi መሣሪያዎች አንጻራዊ ቦታን እንዲያሳውቅ፣ እንዲያገናኝ እና እንዲያውቅ ያስችለዋል"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ተመራጭ NFC የክፍያ አገልግሎት መረጃ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"እንደ የተመዘገቡ እርዳታዎች እና የጉዞ መሥመር መዳረሻ የመሳሰለ ተመራጭ nfc የክፍያ አገልግሎት መረጃን ለማግኘት ለመተግበሪያው ያፈቅድለታል።"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ቅርብ የግኑኙነትመስክ (NFC) ተቆጣጠር"</string>
@@ -726,6 +728,8 @@
<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_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 ኸ በሚበልጥ ፍጥነት ናሙና እንዲያደርግ ይፈቅድለታል"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 14a1ae5..363f833e 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"للسماح للتطبيق بعرض إعلانات على الأجهزة القريبة التي تتضمّن بلوتوث."</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">"التفاعل مع أجهزة Wi‑Fi المجاورة"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"للسماح للتطبيق بالإعلان والربط وتحديد الموقع النسبي لأجهزة Wi-Fi المجاورة."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"يسمح هذا الإذن للتطبيق بالحصول على معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل، مثلاً المساعدات المسجّلة ووجهة المسار."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"التحكم في اتصال الحقل القريب"</string>
@@ -738,6 +740,8 @@
<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_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 هرتز."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"تعيين قواعد كلمة المرور"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 7992f13..7dbeabf 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -291,12 +291,12 @@
<string name="notification_channel_retail_mode" msgid="3732239154256431213">"খুচুৰা ডেম\'"</string>
<string name="notification_channel_usb" msgid="1528280969406244896">"ইউএছবি সংযোগ"</string>
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"এপ্ চলি আছে"</string>
- <string name="notification_channel_foreground_service" msgid="7102189948158885178">"বেটাৰি খৰচ কৰা এপসমূহ"</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_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">"সুৰক্ষিত ম\'ড"</string>
<string name="android_system_label" msgid="5974767339591067210">"Android ছিষ্টেম"</string>
@@ -391,7 +391,7 @@
<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="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>
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"এপ্টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰ কৰিবলৈ দিয়ে"</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">"নিকটৱৰ্তী ৱাই-ফাই ডিভাইচসমূহৰ সৈতে ভাব বিনিময় কৰক"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এপ্টোক বিজ্ঞাপন প্ৰচাৰ কৰিবলৈ, সংযোগ কৰিবলৈ আৰু নিকটৱৰ্তী ৱাই-ফাই ডিভাইচৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"অগ্ৰাধিকাৰ দিয়া NFC পৰিশোধ সেৱাৰ তথ্য"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"এপ্টোক অগ্ৰাধিকাৰ দিয়া nfc পৰিশোধ সেৱাৰ পঞ্জীকৃত সহায়কসমূহ আৰু পৰিশোধ কৰিব লগা লক্ষ্যস্থান দৰে তথ্য পাবলৈ অনুমতি দিয়ে।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়েৰ ফিল্ড কমিউনিকেশ্বন নিয়ন্ত্ৰণ কৰক"</string>
@@ -726,6 +728,8 @@
<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_startViewAppFeatures" msgid="7955084203185903001">"এপৰ সুবিধাসমূহৰ সম্পর্কীয় তথ্য চোৱাটো আৰম্ভ কৰক"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"ধাৰকক কোনো এপৰ সুবিধাসমূহৰ সম্পর্কীয় তথ্য চোৱাটো আৰম্ভ কৰিবলৈ দিয়ে।"</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"এটা উচ্চ ছেম্পলিঙৰ হাৰত ছেন্সৰৰ ডেটা এক্সেছ কৰে"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"এপ্টোক ২০০ হাৰ্টজতকৈ অধিক হাৰত ছেন্সৰৰ ডেটাৰ নমুনা ল’বলৈ অনুমতি দিয়ে"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"পাছৱর্ডৰ নিয়ম ছেট কৰক"</string>
@@ -1467,8 +1471,8 @@
<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_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>
@@ -2108,10 +2112,10 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"অধিক জানক"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12ত Androidৰ অভিযোজিত জাননীক উন্নত জাননীৰ দ্বাৰা সলনি কৰা হৈছে। এই সুবিধাটোৱে পৰামৰ্শ দিয়া কাৰ্য আৰু প্ৰত্যুত্তৰ দেখুৱায় আৰু আপোনাৰ জাননীসমূহ শৃংখলাবদ্ধ কৰে।\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="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_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>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index d269032..e949a53 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -543,6 +543,10 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Tətbiqə yaxınlıqdakı Bluetooth cihazlarında reklam etmək imkanı verir"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"yaxınlıqdakı Ultra Genişzolaqlı cihazları arasında nisbi mövqeyi təyin etmək"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tətbiqə yaxınlıqdakı Ultra Genişzolaqlı cihazları arasında nisbi mövqeyi təyin etməyə icazə verin"</string>
+ <!-- no translation found for permlab_nearby_wifi_devices (392774237063608500) -->
+ <skip />
+ <!-- no translation found for permdesc_nearby_wifi_devices (3054307728646332906) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tərcih edilən NFC ödəniş xidməti məlumatı"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tətbiqə qeydiyyatdan keçmiş yardım və marşrut təyinatı kimi tərcih edilən nfc ödəniş xidməti məlumatını əldə etmək icazəsi verir."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication\'ı kontrol et"</string>
@@ -726,6 +730,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Tətbiqə \"Narahat Etməyin\" konfiqurasiyasını oxumağa və yazmağa icazə verin."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"Baxış icazəsinin istifadəsinə başlayın"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Sahibinə tətbiqin icazədən istifadəsinə başlamağa imkan verir. Adi tətbiqlər üçün heç vaxt tələb edilmir."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"tətbiqin funksiyalarını görməyə başlamaq"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"İstifadəçinin tətbiqin funksiyaları barədə məlumatları görməyə başlamasına icazə verir."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"sensor datasına yüksək ölçmə sürəti ilə giriş etmək"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Tətbiqə sensor datasını 200 Hz-dən yüksək sürətlə ölçməyə imkan verir"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Parol qaydalarını təyin edin"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 1b10856..e7968e5 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -546,6 +546,8 @@
<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>
@@ -729,6 +731,8 @@
<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_startViewAppFeatures" msgid="7955084203185903001">"pokretanje prikaza funkcija aplikacije"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Dozvoljava korisniku 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>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index d4cd127..b06dbd9 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -549,6 +549,8 @@
<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">"Узаемадзеянне з прыладамі з Wi‑Fi паблізу"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Праграма зможа адпраўляць даныя на прылады Wi-Fi паблізу, падключацца да іх і вызначаць іх месцазнаходжанне"</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>
@@ -732,6 +734,8 @@
<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_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 Гц"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Устанавіць правілы паролю"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 1b963f6..256ab09 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -543,6 +543,8 @@
<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">"Взаимодействие с устройствата с Wi-Fi в близост"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Разрешава на приложението да рекламира, да се свързва и да определя относителната позиция на у-вата с Wi-Fi в близост"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информация за предпочитаната услуга за плащане чрез NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дава възможност на приложението да получава информация за предпочитаната услуга за плащане чрез NFC, като например регистрирани помощни средства и местоназначение."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контролиране на комуникацията в близкото поле"</string>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 0f47e29..9f29d8e 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -543,6 +543,10 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"আশেপাশের ব্লুটুথ ডিভাইস বিজ্ঞাপন দেওয়ার জন্য অ্যাপকে অনুমতি দেয়"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"আশেপাশের Ultra-Wideband ডিভাইসগুলির আপেক্ষিক অবস্থান নির্ণয় করুন"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"অ্যাপকে আশেপাশের Ultra-Wideband ডিভাইসগুলির আপেক্ষিক অবস্থান নির্ণয় করার অনুমতি দিন"</string>
+ <!-- no translation found for permlab_nearby_wifi_devices (392774237063608500) -->
+ <skip />
+ <!-- no translation found for permdesc_nearby_wifi_devices (3054307728646332906) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"পছন্দের NFC পেমেন্ট পরিষেবার তথ্য"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"অ্যাপের মাধ্যমে পছন্দসই এনএফসি পেমেন্ট পরিষেবার তথ্য, যেমন রেজিস্ট্রার করার সহায়তা এবং রুট ডেস্টিনেশন সম্পর্কিত তথ্য অ্যাক্সেস করার অনুমতি দেয়।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়ার ফিল্ড কমিউনিকেশন নিয়ন্ত্রণ করে"</string>
@@ -726,6 +730,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"অ্যাপটিকে \'বিরক্ত করবে না\' কনফিগারেশন পড়া এবং লেখার অনুমতি দেয়।"</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"দেখার অনুমতি কাজে লাগানো শুরু করুন"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"কোনও অ্যাপের কোনও নির্দিষ্ট অনুমতির ব্যবহার শুরু করার ক্ষেত্রে হোল্ডারকে সাহায্য করে। সাধারণ অ্যাপের জন্য এটির পরিবর্তন হওয়ার কথা নয়।"</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"হাই স্যাম্পলিং রেটে সেন্সর ডেটা অ্যাক্সেস করুন"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"200 Hz-এর বেশি রেটে অ্যাপকে স্যাম্পল সেন্সর ডেটার জন্য অনুমতি দিন"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"পাসওয়ার্ড নিয়মগুলি সেট করে"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 32bc006..e6bfadcb 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -546,6 +546,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Dozvoljava aplikaciji da vrši oglašavanje na Bluetooth uređajima u blizini"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"određivanje rel. položaja uređaja ultra širokog opsega u blizini"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dozvolite aplikaciji da odredi relativni položaj između uređaja ultra širokog opsega u blizini"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"stupanje u interakciju s WiFi uređajima u blizini"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Dozvoljava aplikaciji da se oglašava, povezuje i određuje relativni položaj WiFi uređaja u blizini"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja putem NFC-a"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da dobije informacije o preferiranoj usluzi plaćanja putem NFC-a kao što su registrirana pomagala i odredište rute."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje NFC-om"</string>
@@ -729,6 +731,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Omogućava aplikaciji da čita i upisuje konfiguraciju načina rada Ne ometaj."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"pokrenuti korištenje odobrenja za pregled"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Dozvoljava vlasniku da pokrene korištenje odobrenja za aplikaciju. Ne bi trebalo biti potrebno za obične aplikacije."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"pokretanje pregleda funkcija aplikacije"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Dozvoljava vlasniku da pokrene pregled informacija o funkcijama za aplikaciju."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"pristup podacima senzora velikom brzinom uzorkovanja"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Dozvoljava aplikaciji da uzorkuje podatke senzora brzinom većom od 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Postavljanje pravila za lozinke"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4bc1ea7..89e466a 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permet que l\'aplicació s\'anunciï als dispositius Bluetooth propers"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar posició entre dispositius de banda ultraampla propers"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permet que l\'aplicació determini la posició relativa entre els dispositius de banda ultraampla propers"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interaccionar amb els dispositius Wi‑Fi propers"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet que l\'aplicació s\'anunciï i es connecti als dispositius Wi‑Fi propers, i en determini la posició relativa"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informació preferent sobre el servei de pagament per NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet que l\'aplicació obtingui informació preferent sobre el servei de pagament per NFC, com ara complements registrats i destinacions de rutes."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicació de camp proper (NFC)"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet que l\'aplicació llegeixi la configuració No molestis i hi escrigui."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"comença a utilitzar el permís de visualització"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet que un propietari comenci a utilitzar el permís amb una aplicació. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"iniciar la visualització de les funcions d\'una aplicació"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permet que el propietari vegi la informació de les funcions d\'una aplicació."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"accedir a les dades del sensor a una freqüència de mostratge alta"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permet que l\'aplicació dugui a terme un mostratge de les dades del sensor a una freqüència superior a 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Definir les normes de contrasenya"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 4de0251..c57d844 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -549,6 +549,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Umožňuje aplikaci inzerovat zařízením Bluetooth v okolí"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"zjišťování vzájemné pozice mezi ultra-širokopásmovými zařízeními v okolí"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikace bude moci zjišťovat vzájemnou pozici mezi ultra-širokopásmovými zařízeními v okolí"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakce se zařízeními Wi-Fi v okolí"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Umožňuje aplikaci inzerovat, připojovat se a odhadovat relativní polohu zařízení Wi-Fi v okolí"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informace o preferované platební službě NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikaci získat informace o preferované platební službě NFC, například o registrovaných pomůckách a cíli směrování."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ovládání technologie NFC"</string>
@@ -732,6 +734,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Umožňuje aplikaci číst a zapisovat konfiguraci režimu Nerušit."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"zahájení zobrazení využití oprávnění"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Umožňuje přístup zahájit využití oprávnění jiné aplikace. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"přístup k datům ze senzorů s vyšší vzorkovací frekvencí"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Umožňuje aplikaci vzorkovat data ze senzorů s frekvencí vyšší než 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Nastavit pravidla pro heslo"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9662952..b868ff8 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Giver appen tilladelse til at give sig til kende for Bluetooth-enheder i nærheden"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"fastlægge den relative position mellem UWB-enheder i nærheden"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tillad, at appen fastlægger den relative position mellem UWB-enheder (Ultra-Wideband) i nærheden"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagere med Wi‑Fi-enheder i nærheden"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Giver appen tilladelse til at informere om, oprette forbindelse til og fastslå den relative placering af Wi‑Fi -enheder i nærheden"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Foretrukne oplysninger vedrørende NFC-betalingstjeneste"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillader, at appen får foretrukne oplysninger vedrørende NFC-betalingstjeneste, f.eks. registrerede hjælpemidler og rutedestinationer."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"administrere Near Field Communication"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Giver appen tilladelse til at læse og redigere konfigurationen af Forstyr ikke."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start brugen at tilladelsesvisning"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Tillader, at brugeren kan bruge en tilladelse for en app. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"se appfunktioner"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Giver den app, som har tilladelsen, mulighed for at se oplysninger om en apps funktioner."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"få adgang til sensordata ved høj samplingfrekvens"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Tillader, at appen kan sample sensordata ved en højere frekvens end 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Angiv regler for adgangskoder"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 368961b..d325ae3 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Erlaubt der App, Inhalte an Bluetooth-Geräte in der Nähe zu senden"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"Relative Distanz zwischen Ultrabreitband-Geräten in der Nähe bestimmen"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ermöglicht der App, die relative Distanz zwischen Ultrabreitband-Geräten in der Nähe zu bestimmen"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Mit WLAN-Geräten in der Nähe interagieren"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Erlaubt der App, Inhalte an WLAN-Geräte in der Nähe zu senden, sich mit ihnen zu verbinden und ihre relative Positionierung zu ermitteln"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informationen zum bevorzugten NFC-Zahlungsdienst"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ermöglicht der App, Informationen zum bevorzugten NFC-Zahlungsdienst abzurufen, etwa registrierte Hilfsmittel oder das Routenziel."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Nahfeldkommunikation steuern"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ermöglicht der App Lese- und Schreibzugriff auf die „Bitte nicht stören“-Konfiguration"</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"Mit der Verwendung der Anzeigeberechtigung beginnen"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Ermöglicht dem Inhaber, die Berechtigungsnutzung für eine App zu beginnen. Sollte für normale Apps nie benötigt werden."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"App-Funktionen ansehen"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Ermöglicht der App, die Informationen über die Funktionen einer anderen App anzusehen."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"Sensordaten mit hoher Frequenz auslesen"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Erlaubt der App, Sensordaten mit einer Frequenz von mehr als 200 Hz auszulesen"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Passwortregeln festlegen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 57598f4..b3a556d 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Επιτρέπει στην εφαρμογή να προβάλλει διαφημίσεις σε κοντινές συσκευές Bluetooth"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"προσδιορισμός σχετ. θέσης μεταξύ κοντινών συσκευών Ultra-Wideband"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Επιτρέψτε στην εφαρμογή να προσδιορίζει τη σχετική θέση μεταξύ κοντινών συσκευών Ultra-Wideband"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"αλληλεπίδραση με κοντινές συσκευές Wi‑Fi"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Επιτρέπει στην εφαρμογή: προβολή διαφημίσεων, σύνδεση και καθορισμό της σχετικής τοποθεσίας των κοντινών συσκευών Wi‑Fi"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Πληροφορίες προτιμώμενης υπηρεσίας πληρωμών NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Επιτρέπει στην εφαρμογή να λαμβάνει πληροφορίες προτιμώμενης υπηρεσίας πληρωμής NFC, όπως καταχωρημένα βοηθήματα και προορισμό διαδρομής."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ελέγχει την Επικοινωνία κοντινού πεδίου (FNC)"</string>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 62fe27d..53753aa 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Allows the app to advertise to nearby Bluetooth devices"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determine relative position between nearby ultra-wideband devices"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"start view app features"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Allows the holder to start viewing the features info for an app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"access sensor data at a high sampling rate"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Allows the app to sample sensor data at a rate greater than 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Set password rules"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 4257d94..bbeb426 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Allows the app to advertise to nearby Bluetooth devices"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determine relative position between nearby ultra-wideband devices"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"start view app features"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Allows the holder to start viewing the features info for an app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"access sensor data at a high sampling rate"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Allows the app to sample sensor data at a rate greater than 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Set password rules"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a686500..16de6b2 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Allows the app to advertise to nearby Bluetooth devices"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determine relative position between nearby ultra-wideband devices"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"start view app features"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Allows the holder to start viewing the features info for an app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"access sensor data at a high sampling rate"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Allows the app to sample sensor data at a rate greater than 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Set password rules"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 89dc230..0b19c5c 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Allows the app to advertise to nearby Bluetooth devices"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determine relative position between nearby ultra-wideband devices"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"start view app features"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Allows the holder to start viewing the features info for an app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"access sensor data at a high sampling rate"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Allows the app to sample sensor data at a rate greater than 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Set password rules"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 2d8d038..7fba349 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Allows the app to advertise to nearby Bluetooth devices"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determine relative position between nearby Ultra-Wideband devices"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby Ultra-Wideband devices"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect, and determine the relative position of nearby Wi‑Fi devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC Payment Service Information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred nfc payment service information like registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near Field Communication"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"start view app features"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Allows the holder to start viewing the features info for an app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"access sensor data at a high sampling rate"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Allows the app to sample sensor data at a rate greater than 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Set password rules"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 843d04f..38b4963 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que la app muestre anuncios a dispositivos Bluetooth cercanos"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar posición entre disposit. Ultra Wideband"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la app determine la posición relativa con dispositivos Ultra Wideband cercanos"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactuar con dispositivos Wi-Fi cercanos"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que la app muestre anuncios, se conecte y determine la posición relativa de los dispositivos Wi-Fi cercanos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre servicio de pago NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la app reciba información del servicio de pago NFC preferido, como el servicio de asistencia registrado y el destino de la ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar la Transmisión de datos en proximidad"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite que la aplicación lea y modifique la configuración de la función No interrumpir."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso de permiso de vista"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que el propietario inicie el uso de permisos para una app. No debería requerirse para apps normales."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"iniciar vista de funciones de la app"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permite que el propietario vea la información de las funciones de una app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"Acceder a los datos del sensor a una tasa de muestreo alta"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permite que la app tome una muestra de los datos del sensor a una tasa superior a 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Establecer reglas de contraseña"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 8127201..4afc20c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que la aplicación emita a dispositivos Bluetooth cercanos"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"calcular posición de dispositivos de banda ultraancha cercanos"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la aplicación determine la posición relativa de los dispositivos de banda ultraancha cercanos"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Interactuar con dispositivos Wi-Fi cercanos"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite a la aplicación mostrar información de dispositivos Wi-Fi cercanos, conectarse a ellos y determinar su posición"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre el servicio de pago por NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la aplicación obtenga información sobre el servicio de pago por NFC preferido, como identificadores de aplicación registrados y destinos de rutas."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicación de campo cercano (NFC)"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite que la aplicación lea y modifique la configuración de No molestar."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso de permiso de visualización"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que el titular inicie el uso de permisos de una aplicación. Las aplicaciones normales no deberían necesitar nunca este permiso."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"acceder a datos de sensores a una frecuencia de muestreo alta"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permite que la aplicación consulte datos de sensores a una frecuencia superior a 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Establecimiento de reglas de contraseña"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 510826e..3320ab2 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Lubab rakendusel läheduses olevatele Bluetooth-seadmetele reklaamida"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"Määrata lähedalasuvate ülilairibaühendust kasutavate seadmete suhtelise kauguse üksteisest."</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Võimaldab rakendusel määrata lähedalasuvate ülilairibaühendust kasutavate seadmete suhtelise kauguse üksteisest"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Läheduses olevate WiFi-seadmetega suhtlemine"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lubab rakendusel läheduses olevatele WiFi-seadmetele reklaamida, nendega ühenduse luua ja määrata nende suhteline asend"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Eelistatud NFC-makseteenuse teave"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Võimaldab rakendusel hankida eelistatud NFC-makseteenuse teavet (nt registreeritud abi ja marsruudi sihtkoht)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"lähiväljaside juhtimine"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Võimaldab rakendusel lugeda ja kirjutada funktsiooni Mitte segada seadistusi."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"vaatamisloa kasutamise alustamine"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Võimaldab omanikul rakenduse puhul alustada loa kasutamist. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"rakenduse funktsioonide vaatamise alustamine"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Võimaldab omanikul alustada rakenduse funktsioonide teabe vaatamist."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"juurdepääs anduri andmetele kõrgel diskreetimissagedusel"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Võimaldab rakendusel anduri andmeid diskreetida sagedusel, mis on suurem kui 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Parooli reeglite määramine"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 5706aa1..dc28a1a 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Inguruko Bluetooth bidezko gailuetan informazioa iragartzeko baimena ematen die aplikazioei"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"banda ultrazabala darabilten inguruko gailuen arteko distantzia erlatiboa zehaztu"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Banda ultrazabala darabilten inguruko gailuen arteko distantzia erlatiboa zehazteko baimena ematen dio aplikazioari"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"inguruko wifi-gailuekin interakzioan jardun"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Inguruko wifi-gailuetan iragartzeko, haiekin konektatzeko eta haien kokapena zehazteko baimena ematen die aplikazioei"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa jasotzeko baimena ematen die aplikazioei, hala nola erregistratutako laguntzaileak eta ibilbidearen helmuga."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolatu Near Field Communication komunikazioa"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ez molestatzeko moduaren konfigurazioa irakurtzeko eta bertan idazteko baimena ematen die aplikazioei."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"hasi ikusteko baimena erabiltzen"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Aplikazioaren baimena erabiltzen hasteko baimena ematen die titularrei. Aplikazio normalek ez lukete beharko."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"hasi aplikazioaren eginbideak ikusten"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Aplikazio baten eginbideei buruzko informazioa ikusten hasteko baimena ematen die titularrei."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"atzitu sentsoreen datuen laginak abiadura handian"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Aplikazioak 200 Hz-tik gorako abiaduran hartu ahal izango ditu sentsoreen datuen laginak"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Ezarri pasahitzen arauak"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 3eb3f3d..7c964ae 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"برنامه مجاز میشود در دستگاههای بلوتوث اطراف تبلیغ کند."</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">"برقراری تعامل با دستگاههای Wi-Fi اطراف"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"به برنامه اجازه میدهد در دستگاههای Wi-Fi اطراف تبلیغ کند، به آنها متصل شود، و موقعیت نسبی آنها را تشخیص دهد"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"اطلاعات ترجیحی سرویس پولی NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"به برنامه اجازه میدهد اطلاعات ترجیحی سرویس پولی NFC، مانند کمکهای ثبتشده و مقصد مسیر را دریافت کند."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"کنترل ارتباط راه نزدیک"</string>
@@ -726,6 +728,8 @@
<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_startViewAppFeatures" msgid="7955084203185903001">"مشاهده ویژگیهای برنامه"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"به دارنده اجازه میدهد اطلاعات مربوط به ویژگیهای برنامه را مشاهده کند."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"دسترسی به دادههای حسگر با نرخ نمونهبرداری بالا"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"به برنامه اجازه میدهد دادههای حسگر را با نرخ بیشاز ۲۰۰ هرتز نمونهبرداری کند"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"تنظیم قوانین گذرواژه"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index d40ed60..aba14ae 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Sallii sovelluksen mainostaa lähellä oleville Bluetooth-laitteille"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"määrittää UVB:ta käyttävien laitteiden suhteellisen sijainnin"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Sallii sovelluksen määrittää UVB-taajuutta käyttävien laitteiden sijainnin suhteessa toisiinsa"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"käyttää lähellä olevia Wi-Fi-laitteita"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Sallii sovelluksen ilmoittaa ja määrittää lähellä olevien Wi-Fi-laitteiden suhteellisen sijainnin sekä yhdistää niihin"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ensisijaiset NFC-maksupalvelutiedot"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Sallii sovelluksen noutaa tietoja rekisteröidyistä sovellustunnuksista, maksureitin kohteesta ja muita ensisijaisia NFC-maksupalvelutietoja."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"hallitse Near Field Communication -tunnistusta"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Sallii sovelluksen lukea ja muokata Älä häiritse -tilan asetuksia."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"aloita katseluoikeuksien käyttö"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Antaa luvanhaltijan käynnistää sovelluksen käyttöoikeuksien käytön. Ei tavallisten sovelluksien käyttöön."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"aloittaa sovellusominaisuuksien katselun"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Antaa luvanhaltijan aloittaa sovelluksen ominaisuustietojen katselun."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"saada pääsyn anturidataan suuremmalla näytteenottotaajuudella"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Sallii sovelluksen ottaa anturidatasta näytteitä yli 200 Hz:n taajuudella"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Asentaa salasanasäännöt"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 43d6c09..56ab0af 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permet à l\'application d\'envoyer des annonces aux appareils Bluetooth à proximité"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autorisez l\'application à déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'application d\'annoncer, de se connecter et de déterminer la position relative des appareils Wi-Fi à proximité"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information sur le service préféré de paiement CCP"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir de l\'information sur le service préféré de paiement CCP comme les aides enregistrées et la route de destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"gérer la communication en champ proche"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"démarrer l\'affichage de l\'usage des autorisations"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet au détenteur de démarrer l\'usage des autorisations pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"accéder aux données des capteurs à un taux d’échantillonnage élevé"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permet à l’application d’échantillonner les données des capteurs à une fréquence supérieure à 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Définir les règles du mot de passe"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a88df26..17ef670 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permet à l\'appli de diffuser du contenu sur les appareils Bluetooth à proximité"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"déterminer position relative entre appareils ultra-wideband à proximité"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autoriser l\'appli à déterminer la position relative entre des appareils ultra-wideband à proximité"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'appli de déterminer la position relative des appareils Wi‑Fi à proximité, vous en informer et s\'y connecter"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informations sur le service de paiement NFC préféré"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir des informations sur le service de paiement NFC préféré, y compris les ID d\'applications et les destinations de routage enregistrés."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"contrôler la communication en champ proche"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"activer l\'utilisation de l\'autorisation d\'affichage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet à l\'application autorisée d\'activer l\'utilisation de l\'autorisation pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"commencer à voir les fonctionnalités d\'une appli"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permet à l\'appli autorisée de commencer à voir les infos sur les fonctionnalités d\'une appli."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"accéder aux données des capteurs à un taux d\'échantillonnage élevé"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Autorise l\'appli à échantillonner les données des capteurs à un taux supérieur à 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Définir les règles du mot de passe"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 74df014..987464a 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -543,6 +543,10 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que a aplicación envíe anuncios a dispositivos Bluetooth próximos"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar posición entre dispositivos próximos"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que a aplicación determine a posición relativa entre os dispositivos próximos que usen banda ultralarga"</string>
+ <!-- no translation found for permlab_nearby_wifi_devices (392774237063608500) -->
+ <skip />
+ <!-- no translation found for permdesc_nearby_wifi_devices (3054307728646332906) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información do servizo de pago de NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a aplicación obteña información do servizo de pago de NFC preferido, como as axudas rexistradas e o destino da ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Near Field Communication"</string>
@@ -726,6 +730,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite á aplicación ler e escribir a configuración do modo Non molestar."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso de permiso de vista"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite ao propietario iniciar o uso de permisos dunha aplicación. As aplicacións normais non deberían precisalo nunca."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"comezar a ver as funcións da aplicación"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permite que o propietario comece a ver a información das funcións dunha aplicación."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"acceder aos datos dos sensores usando unha taxa de mostraxe alta"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permite que a aplicación recompile mostras dos datos dos sensores cunha taxa superior a 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Establecer as normas de contrasinal"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 5b0682b..0a2649d 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"નજીકના બ્લૂટૂથ ડિવાઇસ પર ઍપને જાહેરાત કરવાની મંજૂરી આપે છે"</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">"નજીકના વાઇ-ફાઇ ડિવાઇસ સાથે ક્રિયાપ્રતિક્રિયા કરો"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ઍપને નજીકના વાઇ-ફાઇ ડિવાઇસની માહિતી બતાવવાની, તેની સાથે કનેક્ટ કરવાની અને તેની સંબંધિત સ્થિતિ નક્કી કરવાની મંજૂરી આપો"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"આ મંજૂરીને આપવાથી, ઍપ તમારી પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી મેળવી શકે છે, જેમ કે રજિસ્ટર થયેલી સહાય અને નિર્ધારિત સ્થાન."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"નિઅર ફીલ્ડ કમ્યુનિકેશન નિયંત્રિત કરો"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"એપ્લિકેશનને ખલેલ પાડશો નહીં ગોઠવણી વાંચવા અને લખવાની મંજૂરી આપે છે."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"પરવાનગી વપરાશ જુઓને શરૂ કરો"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"કોઈ ઍપ માટે પરવાનગી વપરાશ શરૂ કરવાની ધારકને મંજૂરી આપે છે. સામાન્ય ઍપ માટે ક્યારેય જરૂર પડી ન શકે."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"ઉચ્ચ સેમ્પ્લિંગ રેટ પર સેન્સરનો ડેટા ઍક્સેસ કરો"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"ઍપને 200 Hzથી વધુના દરે સેન્સરના ડેટાના નમૂનાની મંજૂરી આપે છે"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"પાસવર્ડ નિયમો સેટ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index e7cdae4..1d9230a 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"अनुमति मिलने पर, ऐप्लिकेशन, आस-पास मौजूद ब्लूटूथ डिवाइसों पर विज्ञापन दिखा पाएगा"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"आस-पास मौजूद Ultra-Wideband डिवाइसों के बीच की दूरी का पता लगाएं"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ऐप्लिकेशन को आस-पास मौजूद Ultra-Wideband डिवाइसों के बीच की दूरी का पता लगाने की अनुमति दें"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"आस-पास मौजूद वाई-फ़ाई डिवाइसों से इंटरैक्ट करें"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"इससे, ऐप्लिकेशन आस-पास मौजूद वाई-फ़ाई डिवाइसों की जानकारी दिखा पाएगा, उनसे कनेक्ट कर पाएगा, और उनकी दूरी पता लगा पाएगा"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC का इस्तेमाल करने वाली पैसे चुकाने की पसंदीदा सेवा की जानकारी"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"अगर ऐप्लिकेशन को अनुमति दी जाती है, तो वह पैसे चुकाने की आपकी उस पसंदीदा सेवा के बारे में जानकारी पा सकता है जो NFC का इस्तेमाल करती है. इसमें रजिस्टर किए गए डिवाइस और उनके आउटपुट के रूट जैसी जानकारी शामिल होती है."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"नियर फ़ील्ड कम्यूनिकेशन नियंत्रित करें"</string>
@@ -726,6 +728,8 @@
<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_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 हर्ट्ज़ से ज़्यादा की दर पर सेंसर डेटा का नमूना ले पाएगा"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियम सेट करना"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 04832f7..5f276c3 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -546,6 +546,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Aplikaciji omogućuje oglašavanje na Bluetooth uređajima u blizini"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"odredite približni položaj između uređaja u blizini koji upotrebljavaju ultraširokopojasno povezivanje"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dopušta aplikaciji da odredi približni položaj između uređaja u blizini koji upotrebljavaju ultraširokopojasno povezivanje"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcija s Wi-Fi uređajima u blizini"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Aplikaciji omogućuje oglašavanje, povezivanje i određivanje približnog položaja Wi-Fi uređaja u blizini"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Omogućuje aplikaciji primanje informacija o preferiranoj usluzi plaćanja NFC kao što su registrirana pomagala i odredište."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
@@ -729,6 +731,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Omogućuje aplikaciji čitanje i pisanje konfiguracije opcije Ne uznemiravaj."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"pokrenuti upotrebu dopuštenja za pregled"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Dopušta nositelju pokretanje upotrebe dopuštenja za aplikaciju. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"pristup podacima senzora pri višoj brzini uzorkovanja"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Aplikaciji omogućuje uzorkovanje podataka senzora pri brzini većoj od 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Postavi pravila zaporke"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 4a4e13d..a0f8eac 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Lehetővé teszi az alkalmazás számára, hogy közzétegye jelenlétét a közeli Bluetooth-eszközök számára"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"közeli, ultraszélessávú eszközök közötti relatív pozíció meghatározása"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Az alkalmazás meghatározhatja a közeli, ultraszélessávú eszközök közötti relatív pozíciót"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"műveleteket végezhet a közeli Wi‑Fi-eszközökkel"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Engedélyezi az alkalmazás számára, hogy közzétegye és meghatározza a közeli Wi-Fi-eszközök viszonylagos helyzetét, és csatlakozzon hozzájuk."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferált NFC fizetési szolgáltatási információk"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lehetővé teszi az alkalmazás számára preferált NFC fizetési szolgáltatási információk (pl. regisztrált alkalmazásazonosítók és útvonali cél) lekérését."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC technológia vezérlése"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Az alkalmazás olvashatja és szerkesztheti a „Ne zavarjanak” funkció beállításait."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"engedélyhasználat megtekintésének elindítása"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Lehetővé teszi a felhasználó számára, hogy elindítsa az alkalmazás engedélyhasználatát. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"hozzáférés a szenzoradatokhoz nagy mintavételezési gyakorisággal"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Lehetővé teszi az alkalmazás számára, hogy 200 Hz-nél magasabb gyakorisággal vegyen mintát a szenzoradatokból"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Jelszavakkal kapcsolatos szabályok beállítása"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 389412c..c79d4f5 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Թույլատրում է հավելվածին գովազդ փոխանցել մոտակա Bluetooth սարքերին"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"որոշել մոտակա UWB սարքերի միջև հարաբերական դիրքավորումը"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Թույլատրել հավելվածին որոշել գերլայնաշերտ կապի տեխնոլոգիան աջակցող մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Փոխազդում մոտակա Wi‑Fi սարքերի հետ"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Թույլ է տալիս հավելվածին տվյալներ փոխանցել մոտակա Wi‑Fi սարքերին, միանալ դրանց և որոշել դրանց մոտավոր դիրքը։"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Տեղեկություններ NFC վճարային ծառայության մասին"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Թույլ է տալիս հավելվածին ստանալ նախընտրելի NFC վճարային ծառայության մասին տեղեկություններ (օր․՝ գրանցված լրացուցիչ սարքերի և երթուղու նպատակակետի մասին տվյալներ)։"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"վերահսկել Մոտ Տարածությամբ Հաղորդակցումը"</string>
@@ -726,6 +728,8 @@
<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_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 Հց-ից բարձր հաճախականության վրա"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Սահմանել գաղտնաբառի կանոնները"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 2ad3a55..080f1e1 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Mengizinkan aplikasi untuk menampilkan iklan ke perangkat Bluetooth di sekitar"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Mengizinkan aplikasi menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"berinteraksi dengan perangkat Wi-Fi di sekitar"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Mengizinkan aplikasi menampilkan informasi, menghubungkan, dan menentukan posisi relatif perangkat Wi-Fi di sekitar"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasi Layanan Pembayaran NFC Pilihan"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Mengizinkan aplikasi untuk mendapatkan informasi layanan pembayaran NFC pilihan seperti bantuan terdaftar dan tujuan rute."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrol NFC"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Mengizinkan aplikasi membaca dan menulis konfigurasi status Jangan Ganggu."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"mulai melihat penggunaan izin"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Memungkinkan pemegang memulai penggunaan izin untuk aplikasi. Tidak diperlukan untuk aplikasi normal."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"mulai lihat fitur aplikasi"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Memungkinkan pemegang mulai melihat info fitur untuk aplikasi."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"mengakses data sensor pada frekuensi pengambilan sampel yang tinggi"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Mengizinkan aplikasi mengambil sampel data sensor pada frekuensi yang lebih besar dari 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Setel aturan sandi"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 982b6c2..78e01c9 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Leyfir forritinu að birta nálægum Bluetooth-tækjum auglýsingar"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"ákvarða fjarlægð milli nálægra tækja með ofurbreiðband"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Leyfa forritinu að ákvarða fjarlægð milli nálægra tækja með ofurbreiðband"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"eiga í samskiptum við nálæg WiFi-tæki"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Leyfir forritinu að auglýsa, tengja og áætla staðsetningu nálægra WiFi-tækja"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Upplýsingar um valda NFC-greiðsluþjónustu"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gerir forritinu kleift að fá valda NFC-greiðsluþjónustu, svo sem skráða aðstoð og áfangastað leiðar."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"stjórna nándarsamskiptum (NFC)"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Leyfir forriti að lesa og skrifa í grunnstillingu „Ónáðið ekki“."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"heimildanotkun upphafsyfirlits"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Leyfir handhafa að byrja heimildanotkun fyrir forrit. Ætti aldrei að þurfa fyrir venjuleg forrit."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"byrja að skoða eiginleika forrits"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Leyfir handhafa að skoða upplýsingar um eiginleika tiltekins forrits."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"aðgangur að skynjaragögnum með hárri upptökutíðni"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Leyfir forritinu að nota upptökutíðni yfir 200 Hz fyrir skynjaragögn"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Setja reglur um aðgangsorð"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ad19a87..71cda82 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Consente all\'app di trasmettere annunci ai dispositivi Bluetooth nelle vicinanze"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"Possibilità di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Consenti all\'app di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Interazione con dispositivi Wi-Fi vicini"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Consente all\'app di trasmettere annunci e connettersi a dispositivi Wi‑Fi vicini e di stabilirne la posizione relativa."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informazioni del servizio di pagamento NFC preferito"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Consente all\'app di recuperare informazioni del servizio di pagamento NFC preferito, quali destinazione della route e identificatori applicazione registrati."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controllo Near Field Communication"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Consente all\'app di leggere e modificare la configurazione della funzione Non disturbare."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"avvio dell\'uso dell\'autorizzazione di visualizzazione"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Consente al titolare di avviare l\'uso delle autorizzazioni per un\'app. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"Inizio della visualizzazione di funzionalità delle app"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Consente all\'app che ha questa autorizzazione di iniziare a visualizzare le informazioni relative alle funzionalità di un\'app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"Accesso ai dati dei sensori a una frequenza di campionamento elevata"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Consente all\'app di campionare i dati dei sensori a una frequenza maggiore di 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Impostare regole per le password"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 52539e0..0c5a4a8 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -549,6 +549,8 @@
<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">"אינטראקציה עם מכשירי Wi-Fi בקרבת מקום"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"האפליקציה תוכל לפרסם במכשירי Wi-Fi בקרבת מקום, להתחבר אליהם ולהעריך את המיקום היחסי שלהם"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"פרטים על שירות תשלום מועדף ב-NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"מאפשרת לאפליקציה לקבל פרטים על שירות תשלום מועדף ב-NFC, כמו עזרים רשומים ויעד של נתיב."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"שליטה בתקשורת מטווח קצר"</string>
@@ -732,6 +734,8 @@
<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_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 הרץ"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"הגדרת כללי סיסמה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 962b65b..911b6d2 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"付近の Bluetooth デバイスへの広告の配信をアプリに許可します"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"付近の Ultra Wideband デバイス間の相対位置の特定"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"付近の Ultra Wideband デバイス間の相対位置の特定をアプリに許可します"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"付近の Wi-Fi デバイスとのやり取り"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"付近の Wi-Fi デバイスについて、情報の表示、接続、相対位置の確認をアプリに許可します"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"優先される NFC お支払いサービスの情報"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"登録されている支援やルートの目的地など、優先される NFC お支払いサービスの情報を取得することをアプリに許可します。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFCの管理"</string>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index bb307f9..d5b92b7 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -543,6 +543,8 @@
<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">"ინტერაქცია ახლომახლო Wi-Fi მოწყობილობებთან"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"საშუალებას აძლევს აპს, განაცხადოს ახლომახლო Wi-Fi მოწყობილობების შესახებ, დაუკავშირდეს მათ და განსაზღვროს მათი შედარებითი პოზიცია"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"უპირატესი NFC გადახდის სერვისის ინფორმაცია"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"საშუალებას აძლევს აპს, მიიღოს უპირატესი NFC გადახდის სერვისის ინფორმაცია, მაგალითად, რეგისტრირებული დახმარება და დანიშნულება."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ახლო მოქმედების რადიოკავშირი (NFC) მართვა"</string>
@@ -726,6 +728,8 @@
<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_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 ჰც-ზე მეტი სიხშირით"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"პაროლის წესების დაყენება"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 1e84e78..05da5fd 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -543,6 +543,10 @@
<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>
+ <!-- no translation found for permlab_nearby_wifi_devices (392774237063608500) -->
+ <skip />
+ <!-- no translation found for permdesc_nearby_wifi_devices (3054307728646332906) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Таңдаулы NFC төлеу қызметі туралы ақпарат"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Қолданба тіркелген көмектер және баратын жер маршруты сияқты таңдаулы NFC төлеу қызметі туралы ақпаратты ала алатын болады."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC функциясын басқару"</string>
@@ -726,6 +730,8 @@
<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_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 Гц-тен жоғары датчик деректерінің үлгісін таңдауға рұқсат береді."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Құпия сөз ережелерін тағайындау"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 406e0a5..6dc8abd 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"អនុញ្ញាតឱ្យកម្មវិធីផ្សាយពាណិជ្ជកម្មទៅឧបករណ៍ប៊្លូធូសដែលនៅជិត"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"កំណត់ចម្ងាយពាក់ព័ន្ធរវាងឧបករណ៍ Ultra-Wideband ដែលនៅជិត"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"អនុញ្ញាតឱ្យកម្មវិធីកំណត់ចម្ងាយពាក់ព័ន្ធរវាងឧបករណ៍ Ultra-Wideband ដែលនៅជិត"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ធ្វើអន្តរកម្មជាមួយឧបករណ៍ Wi‑Fi ដែលនៅជិត"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"អនុញ្ញាតឱ្យកម្មវិធីផ្សាយពាណិជ្ជកម្ម ភ្ជាប់ និងកំណត់ទីតាំងពាក់ព័ន្ធរបស់ឧបករណ៍ Wi‑Fi ដែលនៅជិត"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ព័ត៌មានអំពីសេវាបង់ប្រាក់តាម NFC ជាអាទិភាព"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"អនុញ្ញាតឱ្យកម្មវិធីទទួលបានព័ត៌មានអំពីសេវាបង់ប្រាក់តាម nfc ជាអាទិភាពដូចជា គោលដៅផ្លូវ និងព័ត៌មានកំណត់អត្តសញ្ញាណកម្មវិធី ដែលបានចុះឈ្មោះជាដើម។"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ពិនិត្យការទាក់ទងនៅក្បែរ (NFC)"</string>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index c8edc77..89a5043 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"ಸಮೀಪದ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳಿಗೆ ಜಾಹೀರಾತು ನೀಡಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</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">"ಹತ್ತಿರದ ವೈ -ಫೈ ಸಾಧನಗಳ ಜೊತೆಗೆ ಸಂವಹನ ನಡೆಸಿ"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ಹತ್ತಿರದ ವೈ -ಫೈ ಸಾಧನಗಳ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ಸೂಚಿಸಲು, ಕನೆಕ್ಟ್ ಮಾಡಲು ಮತ್ತು ನಿರ್ಧರಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವಾ ಮಾಹಿತಿ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ನೋಂದಾಯಿತ ಅಪ್ಲಿಕೇಶನ್ ಗುರುತಿಸುವಿಕೆಗಳು ಮತ್ತು ಮಾರ್ಗ ಗಮ್ಯಸ್ಥಾನಗಳಂತಹ ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವೆಗಳ ಬಗ್ಗೆ ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ಸಮೀಪ ಕ್ಷೇತ್ರ ಸಂವಹನವನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಓದಲು ಮತ್ತು ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ವೀಕ್ಷಣಾ ಅನುಮತಿಯ ಬಳಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಿ"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ಆ್ಯಪ್ಗಾಗಿ ಅನುಮತಿ ಬಳಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸಾಮಾನ್ಯ ಆ್ಯಪ್ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"ಹೆಚ್ಚಿನ ನಮೂನೆ ದರದಲ್ಲಿ ಸೆನ್ಸಾರ್ ಡೇಟಾ ಪ್ರವೇಶಿಸಿ"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"200 Hz ಗಿಂತಲೂ ಹೆಚ್ಚಿನ ವೇಗದಲ್ಲಿ ಸೆನ್ಸಾರ್ ಡೇಟಾದ ಮಾದರಿ ಪರೀಕ್ಷಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"ಪಾಸ್ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 4e67b19..5c4c93c 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"앱에서 근처의 블루투스 기기로 광고하도록 허용"</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">"근처 Wi‑Fi 기기와 상호작용"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"앱이 광역 신호를 보내 근처에 있는 Wi‑Fi 기기의 상대적인 위치를 확인하고 연결할 수 있도록 허용합니다."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"기본 NFC 결제 서비스 정보"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"앱이 등록된 AID와 경로 목적지 같은 기본 NFC 결제 서비스 정보를 확인하도록 허용합니다."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC(Near Field Communication) 제어"</string>
@@ -726,6 +728,8 @@
<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_startViewAppFeatures" msgid="7955084203185903001">"앱 기능 보기"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"권한을 보유한 앱에서 앱의 기능 정보를 보도록 허용합니다."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"더 높은 샘플링 레이트로 센서 데이터 액세스"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"앱에서 200Hz보다 빠른 속도로 센서 데이터를 샘플링하도록 허용합니다."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"비밀번호 규칙 설정"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 0568133..87faa67 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -543,6 +543,8 @@
<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">"жакын жердеги Wi‑Fi түзмөктөрү менен байланышуу"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Колдонмого жарнама көрсөтүүгө, байланышууга жана жакын жердеги Wi‑Fi түзмөктөрүн аныктоого мүмкүндүк берет"</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>
@@ -726,6 +728,8 @@
<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_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 Герцтен жогору болгон үлгүлөрдү алууга уруксат берет"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Сырсөз эрежелерин коюу"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index fe39b00..2d8aef7 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"ອະນຸຍາດໃຫ້ແອັບໂຄສະນາຫາອຸປະກອນ Bluetooth ທີ່ຢູ່ໃກ້ຄຽງໄດ້"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"ກຳນົດຕຳແໜ່ງທີ່ສຳພັນກັນລະຫວ່າງອຸປະກອນ Ultra-Wideband ທີ່ຢູ່ໃກ້ຄຽງ"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ອະນຸຍາດໃຫ້ແອັບກຳນົດຕຳແໜ່ງທີ່ສຳພັນກັນລະຫວ່າງອຸປະກອນ Ultra-Wideband ທີ່ຢູ່ໃກ້ຄຽງ"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ໂຕ້ຕອບກັບອຸປະກອນ Wi‑Fi ທີ່ຢູ່ໃກ້ຄຽງ"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ອະນຸຍາດໃຫ້ແອັບໂຄສະນາ, ເຊື່ອມຕໍ່ ແລະ ກຳນົດຕຳແໜ່ງສຳພັນຂອງອຸປະກອນ Wi-Fi ທີ່ຢູ່ໃກ້ຄຽງໄດ້"</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>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index aa70bd2..66b30aa 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -549,6 +549,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Programai leidžiama reklamuoti netoliese esančiuose „Bluetooth“ įrenginiuose"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"nustatyti apyt. netoliese es. itin plataus dažnio juostos įreng. poziciją"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Leisti programai nustatyti apytikslę netoliese esančių itin plataus dažnio juostos įrenginių poziciją"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"sąveikauti su „Wi‑Fi“ įrenginiais netoliese"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Leidžiama programai reklamuoti, prisijungti ir nustatyti apytikslę netoliese esančių „Wi-Fi“ įrenginių poziciją"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Pageidaujama ARL mokėjimo paslaugos informacija"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Programai leidžiama gauti pageidaujamą ARL mokamos paslaugos informaciją, pvz., užregistruotą pagalbą ir maršrutų tikslus."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"valdyti artimo lauko perdavimą (angl. „Near Field Communication“)"</string>
@@ -732,6 +734,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Leidžiama programai skaityti ir rašyti „Do Not Disturb“ konfigūraciją."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"pradėti peržiūrėti leidimo naudojimą"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Leidžia savininkui pradėti naudoti programos leidimą. Įprastoms programoms to neturėtų prireikti."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"pradėti programos funkcijų peržiūrą"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Savininkui leidžiama pradėti programos funkcijų informacijos peržiūrą."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"pasiekti jutiklių duomenis dideliu skaitmeninimo dažniu"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Programai leidžiama skaitmeninti jutiklių duomenis didesniu nei 200 Hz dažniu"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Nustatyti slaptažodžio taisykles"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index b36cf76..db4ae0b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -546,6 +546,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Atļauj lietotnei veikt reklamēšanu tuvumā esošās Bluetooth ierīcēs"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"novietojums starp tuvējām ultraplatjoslas ierīcēm"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Atļaut lietotnei noteikt relatīvo atrašanās vietu starp tuvumā esošām ultraplatjoslas ierīcēm"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Mijiedarbība ar tuvumā esošām Wi‑Fi ierīcēm"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Atļauj lietotnei nodot datus tuvumā esošām Wi‑Fi ierīcē, izveidot savienojumu ar tām un noteikt to relatīvo pozīciju."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informācija par vēlamo NFC maksājumu pakalpojumu"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ļauj lietotnei iegūt informāciju par vēlamo NFC maksājumu pakalpojumu, piemēram, par reģistrētajiem lietojumprogrammu ID un maršruta galamērķi."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolē tuvlauka saziņu"</string>
@@ -729,6 +731,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ļauj lietotnei lasīt un rakstīt režīma “Netraucēt” konfigurāciju."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"Datu skatīšana par izmantojamajām atļaujām"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Ļauj atļaujas īpašniekam sākt lietotnes atļauju izmantošanu. Parastām lietotnēm tas nekad nav nepieciešams."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"Skatīt lietotnes funkcijas"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Lietotne ar šo atļauju var skatīt informāciju par citas lietotnes funkcijām."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"piekļuve sensoru datiem, izmantojot augstu iztveršanas frekvenci"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Ļauj lietotnei iztvert sensoru datus, izmantojot frekvenci, kas ir augstāka par 200 Hz."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Paroles kārtulu iestatīšana"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 396097d..e863205 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -543,6 +543,8 @@
<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">"да има интеракција со уредите со Wi‑Fi во близина"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Дозволува апликацијата да рекламира, да се поврзува и да ја одредува релативната положба уредите со Wi‑Fi во близина"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информации за претпочитаната услуга за плаќање преку NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволува апликацијата да добие информации за претпочитаната услуга за плаќање преку NFC, како регистрирани помагала и дестинација на маршрутата."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контролирај комуникација на блиско поле"</string>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 1dfb50b..95f3fa1 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -543,6 +543,8 @@
<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">"സമീപമുള്ള വൈഫൈ ഉപകരണങ്ങളുമായി ഇടപഴകുക"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"സമീപമുള്ള വൈഫൈ ഉപകരണത്തെ കാണിക്കാനും അവയിലേക്ക് കണക്റ്റ് ചെയ്യാനും അവയുടെ ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാനും ആപ്പിനെ അനുവദിക്കൂ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"തിരഞ്ഞെടുത്ത NFC പേയ്മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"റൂട്ട് ലക്ഷ്യസ്ഥാനം, രജിസ്റ്റർ ചെയ്തിരിക്കുന്ന സഹായങ്ങൾ എന്നിവ പോലുള്ള, തിരഞ്ഞെടുത്ത NFC പേയ്മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ ലഭിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"സമീപ ഫീൽഡുമായുള്ള ആശയവിനിമയം നിയന്ത്രിക്കുക"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"\'ശല്യപ്പെടുത്തരുത്\' കോൺഫിഗറേഷൻ വായിക്കുന്നതിനും എഴുതുന്നതിനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"അനുമതി ഉപയോഗം കാണാൻ ആരംഭിക്കുക"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ഒരു ആപ്പിനുള്ള അനുമതി ഉപയോഗം ആരംഭിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ ആപ്പുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"ഉയർന്ന സാംപ്ലിംഗ് റേറ്റിൽ സെൻസർ ഡാറ്റ ആക്സസ് ചെയ്യുക"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"200 Hz-നേക്കാൾ ഉയർന്ന റേറ്റിൽ സെൻസർ ഡാറ്റ സാമ്പിൾ ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"പാസ്വേഡ് നിയമങ്ങൾ സജ്ജീകരിക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index f479b73..e8fdc15 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -543,6 +543,8 @@
<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">"ойролцоох Wi-Fi төхөөрөмжүүдтэй харилцах"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Аппад ойролцоох Wi-Fi төхөөрөмжүүдтэй холбоотой байрлалыг мэдэгдэх, холбох, тодорхойлохыг зөвшөөрнө"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сонгосон NFC төлбөрийн үйлчилгээний мэдээлэл"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Бүртгүүлсэн төхөөрөмж болон маршрутын хүрэх цэг зэрэг сонгосон nfc төлбөрийн үйлчилгээний мэдээллийг авахыг аппад зөвшөөрдөг."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ойролцоо талбарын холбоог удирдах"</string>
@@ -726,6 +728,8 @@
<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_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 Гц-ээс их хувиар мэдрэгчийн өгөгдлийг түүвэрлэх боломжийг олгодог"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Нууц үгний дүрмийг тохируулах"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 6aa9330..a57f60d 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"जवळपासच्या ब्लूटूथ डिव्हाइसवर जाहिरात करण्याची ॲपला परवानगी देते"</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">"जवळपासच्या वाय-फाय डिव्हाइसशी संवाद साधा"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ॲपला जाहिरात करण्याची, कनेक्ट करण्याची आणि जवळपासच्या वाय-फाय डिव्हाइसचे संबंधित स्थान निर्धारित करण्याची परवानगी देते"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"प्राधान्यकृत NFC पेमेंट सेवा माहिती"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"नोंदणीकृत एड्स आणि मार्ग गंतव्यस्थान सारखी प्राधान्यकृत एनएफसी पेमेंट सेवेची माहिती मिळवण्यासाठी अॅपला अनुमती देते."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"फील्ड जवळील कम्युनिकेशन नियंत्रित करा"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"व्यत्यय आणू नका कॉंफिगरेशन वाचण्यासाठी आणि लिहिण्यासाठी ॲपला अनुमती देते."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"व्ह्यू परवानगी वापर सुरू करा"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"धारकास अॅपसाठी परवानगी वापरणे सुरू करण्याची अनुमती देते. सामान्य अॅप्ससाठी कधीही आवश्यकता नसते."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"उच्च नमुना दराने सेन्सर डेटा अॅक्सेस करते"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"ॲपला २०० Hz पेक्षा जास्त दराने सेन्सर डेटाचा नमुना तयार करण्याची अनुमती देते"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियम सेट करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 6021f70..50ca2d9 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Membenarkan apl menyiarkan kandungan kepada peranti Bluetooth yang berdekatan"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"tentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Benarkan apl menentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"berinteraksi dengan peranti Wi-Fi berdekatan"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Membenarkan apl mengiklankan, menyambung dan menentukan penempatan relatif peranti Wi-Fi berdekatan"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maklumat Perkhidmatan Pembayaran NFC Pilihan"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Membenarkan apl mendapatkan maklumat perkhidmatan pembayaran nfc pilihan seperti bantuan berdaftar dan destinasi laluan."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"mengawal Komunikasi Medan Dekat"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Membenarkan apl membaca dan menulis konfigurasi Jangan Ganggu."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"mulakan lihat penggunaan kebenaran"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Membenarkan pemegang memulakan penggunaan kebenaran untuk apl. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"mula melihat ciri apl"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Membenarkan pemegang mula melihat maklumat ciri untuk apl."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"akses data penderia pada data pensampelan yang tinggi"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Membenarkan apl mengambil sampel data penderia pada kadar yang lebih besar daripada 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Tetapkan peraturan kata laluan"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 8f415ec..6874414 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"အနီးတစ်ဝိုက်ရှိ ဘလူးတုသ်သုံးစက်များတွင် ကြော်ငြာရန် အက်ပ်အား ခွင့်ပြုမည်"</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">"အနီးရှိ Wi-Fi စက်များနှင့် ပြန်လှန်တုံ့ပြန်ခြင်း"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"အက်ပ်ကို ကြော်ငြာရန်၊ ချိတ်ဆက်ရန်နှင့် အနီးတစ်ဝိုက်ရှိ Wi-Fi စက်များ၏ ဆက်စပ်နေရာကို သတ်မှတ်ရန် ခွင့်ပြုနိုင်သည်"</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>
@@ -726,6 +728,8 @@
<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_startViewAppFeatures" msgid="7955084203185903001">"အက်ပ်ဝန်ဆောင်မှုများကို စတင်ကြည့်ခြင်း"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"ဝန်ဆောင်မှုအချက်အလက်ကိုများကို ခွင့်ပြုချက်ရထားသည့် အက်ပ်အား စတင်ကြည့်နိုင်ရန် ခွင့်ပြုသည်။"</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"နမူနာနှုန်းမြင့်သော အာရုံခံစနစ်ဒေတာကို သုံးပါ"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"၂၀၀ Hz နှုန်းထက်ပိုများသော အာရုံခံစနစ်ဒေတာကို နမူနာယူရန် အက်ပ်အား ခွင့်ပြုပါ"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"စကားဝှက်စည်းမျဥ်းကိုသတ်မှတ်ရန်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index ec4378f..e26e41a 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Lar appen vise annonser til Bluetooth-enheter i nærheten"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"fastslå relativ posisjon mellom enheter som bruker ultrabredbånd"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"tillate at appen fastslår den relative posisjonen mellom enheter i nærheten som bruker ultrabredbånd"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"samhandle med Wi-Fi-enheter i nærheten"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lar appen annonsere, koble til og fastslå den relative posisjonen til Wi-Fi-enheter i nærheten"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasjon om prioritert NFC-betalingstjeneste"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gir appen tilgang til informasjon om prioritert NFC-betalingstjeneste, for eksempel registrerte hjelpemidler og destinasjon."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontroller overføring av data med NFC-teknologi"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Lar appen lese og skrive konfigurasjon av Ikke forstyrr."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start visning av bruk av tillatelser"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Lar innehaveren starte bruk av tillatelser for en app. Dette skal aldri være nødvendig for vanlige apper."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"starte visning av appfunksjoner"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Lar innehaveren se informasjon om funksjonene for en app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"tilgang til sensordata ved høy samplingfrekvens"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Lar appen samle inn sensordata ved en hastighet som er høyere enn 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Angi passordregler"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 9d74bb0..c6f3826 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"यो एपले नजिकै रहेका ब्लुटुथ चल्ने डिभाइसहरूमा विज्ञापन गर्न पाउँछ"</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">"Wi-Fi चल्ने नजिकै रहेका डिभाइसहरूमा चलाउन दिन्छ"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"यसले एपलाई Wi-Fi चल्ने नजिकै रहेका डिभाइसहरूमा विज्ञापन गर्न, कनेक्ट गर्न र सापेक्ष स्थिति निर्धारण गर्न दिन्छ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC भुक्तानी सेवासम्बन्धी रुचाइएको जानकारी"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"यसले एपलाई दर्ता गरिएका सहायता तथा मार्गको गन्तव्य जस्ता रुचाइएका NFC भुक्तानी सेवासम्बन्धी जानकारी प्राप्त गर्न दिन्छ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"नजिक क्षेत्र संचार नियन्त्रणहरू"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"बाधा नपुर्याउँनुहोस् कन्फिगरेसन पढ्न र लेख्नको लागि एपलाई अनुमति दिनुहोस्।"</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"हेर्ने अनुमतिको प्रयोग सुरु गर्नुहोस्"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"वाहकलाई कुनै एपसम्बन्धी अनुमतिको प्रयोग सुरु गर्न दिन्छ। साधारण एपहरूलाई कहिल्यै आवश्यक नपर्नु पर्ने हो।"</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"नमुना लिने उच्च दरमा सेन्सरसम्बन्धी डेटा प्रयोग गर्ने"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"यो अनुमति दिइएमा एपले २०० हर्जभन्दा बढी दरमा सेन्सरसम्बन्धी डेटाको नमुना लिन सक्छ"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 06ef43e..9bd6a28 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Hiermee kan de app adverteren op bluetooth-apparaten in de buurt"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"relatieve positie tussen ultrabreedbandapparaten in de buurt bepalen"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"De app toestaan om de relatieve positie tussen ultrabreedbandapparaten in de buurt te bepalen"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactie met wifi-apparaten in de buurt"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Hiermee kan de app adverteren op, verbinding maken met en de relatieve positie bepalen van wifi-apparaten in de buurt"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informatie over voorkeursservice voor NFC-betaling"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Hiermee kun je zorgen dat de app informatie krijgt over de voorkeursservice voor NFC-betaling, zoals geregistreerde hulpmiddelen en routebestemmingen."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication regelen"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Hiermee kan de app configuratie voor Niet storen lezen en schrijven."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"rechtengebruik starten"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Hiermee kan de houder het rechtengebruik voor een app starten. Nooit vereist voor normale apps."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"app-functies bekijken"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Hiermee kan de houder informatie over functies bekijken voor een app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"toegang krijgen tot sensorgegevens met een hoge samplingsnelheid"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Hiermee kan de app sensorgegevens samplen met een snelheid die hoger is dan 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Wachtwoordregels instellen"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index edc206b..cc368a0 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"ଆଖପାଖର ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକରେ ବିଜ୍ଞାପନ ଦେବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</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">"ଆଖପାଖର ୱାଇ-ଫାଇ ଡିଭାଇସଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରନ୍ତୁ"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ଆଖପାଖର ୱାଇ-ଫାଇ ଡିଭାଇସରେ ବିଜ୍ଞାପନ ଦେବା, ତା ସହ ସଂଯୋଗ କରିବା ଓ ତା’ର ଆପେକ୍ଷିକ ଅବସ୍ଥିତି ନିର୍ଦ୍ଧାରଣ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ପସନ୍ଦର NFC ପେମେଣ୍ଟ ସେବା ସୂଚନା"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ପଞ୍ଜିକୃତ ଯନ୍ତ୍ର ଏବଂ ମାର୍ଗ ଲକ୍ଷସ୍ଥଳ ପରି ପସନ୍ଦର nfc ପେମେଣ୍ଟ ସେବା ସୂଚନା ପାଇବାକୁ ଆପ୍ ଅନୁମତି କରିଥାଏ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ନିଅର୍ ଫିଲ୍ଡ କମ୍ୟୁନିକେଶନ୍ ଉପରେ ନିୟନ୍ତ୍ରଣ ରଖନ୍ତୁ"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" କନଫିଗରେଶନ୍ ପଢ଼ିବା ତଥା ଲେଖିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ଅନୁମତି ବ୍ୟବହାର ଦେଖିବା ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ଏକ ଆପ୍ ପାଇଁ ଅନୁମତିର ବ୍ୟବହାର ଆରମ୍ଭ କରିବାକୁ ଧାରକକୁ ଅନୁମତି ଦେଇଥାଏ। ସାଧାରଣ ଆପ୍ଗୁଡ଼ିକ ପାଇଁ ଏହା ଆବଶ୍ୟକ ନୁହେଁ।"</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"ଏକ ଉଚ୍ଚ ନମୁନାକରଣ ରେଟରେ ସେନ୍ସର୍ ଡାଟାକୁ ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"200 Hz ଠାରୁ ଅଧିକ ଏକ ରେଟରେ ସେନ୍ସର୍ ଡାଟାର ନମୁନା ନେବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"ପାସ୍ୱର୍ଡ ନିୟମାବଳୀ ସେଟ୍ କରନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 7f7c6b6..9090830 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -543,6 +543,10 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ \'ਤੇ ਵਿਗਿਆਪਨ ਦੇਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"ਨਜ਼ਦੀਕੀ ਅਲਟ੍ਰਾ-ਵਾਈਡਬੈਂਡ ਡੀਵਾਈਸਾਂ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨਿਰਧਾਰਿਤ ਕਰੋ"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਅਲਟ੍ਰਾ-ਵਾਈਡਬੈਂਡ ਡੀਵਾਈਸਾਂ ਦੇ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨੂੰ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ"</string>
+ <!-- no translation found for permlab_nearby_wifi_devices (392774237063608500) -->
+ <skip />
+ <!-- no translation found for permdesc_nearby_wifi_devices (3054307728646332906) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ਐਪ ਨੂੰ ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ ਕਿ ਰਜਿਸਟਰ ਕੀਤੇ ਸਾਧਨ ਅਤੇ ਮੰਜ਼ਿਲ ਰਸਤਾ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
@@ -726,6 +730,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"ਐਪ ਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਕੌਂਫਿਗਰੇਸ਼ਨ ਨੂੰ ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਦੇਖਣਾ ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ਧਾਰਕ ਨੂੰ ਕਿਸੇ ਹੋਰ ਐਪ ਲਈ ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"ਉੱਚ ਸੈਂਪਲਿੰਗ ਰੇਟ \'ਤੇ ਸੈਂਸਰ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"ਐਪ ਨੂੰ 200 Hz ਤੋਂ ਵੱਧ ਦੀ ਦਰ \'ਤੇ ਸੈਂਸਰ ਡਾਟੇ ਦਾ ਨਮੂਨਾ ਲੈਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"ਪਾਸਵਰਡ ਨਿਯਮ ਸੈੱਟ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 176dffe..af2b120 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -549,6 +549,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Zezwala na kierowanie przez aplikację informacji do urządzeń Bluetooth w pobliżu"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"określanie względnego położenia urządzeń ultraszerokopasmowych w pobliżu"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Zezwól na określanie przez aplikację względnego położenia urządzeń ultraszerokopasmowych w pobliżu"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcje z urządzeniami Wi-Fi w pobliżu"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Zezwala aplikacji na przesyłanie informacji o sobie, łączenie się z urządzeniami Wi‑Fi w pobliżu i określanie ich względnego położenia"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacje o preferowanych usługach płatniczych NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pozwala aplikacji uzyskiwać informacje o preferowanych usługach płatniczych NFC, np. zarejestrowanych pomocach i miejscach docelowych tras."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolowanie łączności Near Field Communication"</string>
@@ -732,6 +734,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Pozwala aplikacji na odczyt i zmianę konfiguracji trybu Nie przeszkadzać."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"rozpocząć wyświetlanie użycia uprawnień"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Umożliwia rozpoczęcie korzystania z uprawnienia dotyczącego danej aplikacji jego posiadaczowi. Zwykłe aplikacje nie powinny potrzebować tego uprawnienia."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"rozpoczęcie wyświetlania funkcji aplikacji"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Umożliwia posiadaczowi rozpoczęcie przeglądania informacji o funkcjach aplikacji."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"dostęp do danych czujnika z wysoką częstotliwością"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Zezwala aplikacji na pobieranie próbek danych z czujnika z częstotliwością wyższą niż 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Określ reguły hasła"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index a4eb8f6..1f9c0775 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que o app seja anunciado em dispositivos Bluetooth por perto"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi-Fi por perto"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app veicule anúncios, conecte-se à rede e determine a posição relativa de dispositivos Wi-Fi por perto"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permitir que o app leia e grave a configuração \"Não perturbe\"."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso da permissão para visualização"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que o sistema inicie o uso de permissão para um app. Não deve ser necessário para apps comuns."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"ver recursos do app"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permite que o sistema comece a ver as informações de recursos de um app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"acessar os dados do sensor em uma taxa de amostragem elevada"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permite que o app receba amostras de dados do sensor em uma taxa maior que 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Definir regras para senha"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 7e9520d..7006273 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que a app transmita para dispositivos Bluetooth próximos"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar posição relativa dispos. de banda ultralarga próximos"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permita que a app determine a posição relativa entre os dispositivos de banda ultralarga próximos"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi‑Fi próximos"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que a app anuncie, estabeleça ligação e determine a posição relativa de dispositivos Wi‑Fi próximos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações de serviços de pagamento com NFC preferenciais"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a app obtenha informações de serviços de pagamento com NFC preferenciais, como apoios registados e destino da rota."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlo Near Field Communication"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite à app ler e alterar a configuração de Não incomodar"</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar utilização da autorização de visualização"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que o titular inicie a utilização de autorizações para uma app. Nunca deverá ser necessário para aplicações normais."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"começar a ver as funcionalidades da app"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permite que o titular comece a ver as informações das funcionalidades de uma app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"aceder aos dados de sensores a uma taxa de amostragem elevada"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permite que a app obtenha uma amostra dos dados de sensores a uma taxa superior a 200 Hz."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Definir regras de palavra-passe"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a4eb8f6..1f9c0775 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que o app seja anunciado em dispositivos Bluetooth por perto"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi-Fi por perto"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app veicule anúncios, conecte-se à rede e determine a posição relativa de dispositivos Wi-Fi por perto"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permitir que o app leia e grave a configuração \"Não perturbe\"."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso da permissão para visualização"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que o sistema inicie o uso de permissão para um app. Não deve ser necessário para apps comuns."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"ver recursos do app"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permite que o sistema comece a ver as informações de recursos de um app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"acessar os dados do sensor em uma taxa de amostragem elevada"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permite que o app receba amostras de dados do sensor em uma taxa maior que 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Definir regras para senha"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index adb5618..5bbad82 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -546,6 +546,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite aplicației să difuzeze anunțuri pe dispozitive Bluetooth din apropiere"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permiteți-i aplicației să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"să interacționeze cu dispozitive Wi‑Fi din apropiere"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite aplicației să se conecteze la, să afișeze date și să stabilească poziția relativă pentru dispozitive Wi-Fi din apropiere"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informații despre serviciul de plăți NFC preferat"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite aplicației să obțină informații despre serviciul de plăți NFC preferat, de exemplu, identificatorii de aplicație înregistrați și destinația traseului."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlare schimb de date prin Near Field Communication"</string>
@@ -729,6 +731,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite aplicației să citească și să scrie configurația Nu deranja."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"porniți folosirea permisiunii de vizualizare"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite proprietarului să pornească folosirea permisiunii pentru o aplicație. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"începeți să vedeți funcțiile aplicației"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permite proprietarului să înceapă să vadă informațiile despre funcții pentru o aplicație."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"să acceseze date de la senzori la o rată de eșantionare mare"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permite aplicației să colecteze date de la senzori la o rată de eșantionare de peste 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Să seteze reguli pentru parolă"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index acdc7db..b8f190f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -549,6 +549,8 @@
<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">"Взаимодействие с устройствами Wi‑Fi поблизости"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Приложение сможет передавать данные на устройства Wi‑Fi рядом, подключаться к ним и определять их примерное местоположение."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сведения о предпочтительном платежном сервисе NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Приложение сможет получать сведения о предпочтительном платежном сервисе NFC (например, зарегистрированные идентификаторы AID и конечный пункт маршрута)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Управление NFC-модулем"</string>
@@ -732,6 +734,8 @@
<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_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 Гц."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Настройка правил для паролей"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index f565433..6b1b614 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"අවට ඇති බ්ලූටූත් උපාංගවලට වෙළඳ ප්රචාරණය කිරීමට යෙදුමට ඉඩ දෙයි"</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">"අවට Wi‑Fi උපාංග සමග අන්තර්ක්රියා කරන්න"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"වෙළඳ දැන්වීම් පළ කිරීමට, සම්බන්ධ වීමට සහ අවට ඇති Wi-Fi උපාංගවල සාපේක්ෂ පිහිටීම නිර්ණය කිරීමට යෙදුමට ඉඩ දෙයි"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"කැමති NFC ගෙවීම් සේවා තොරතුරු"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ලියාපදිංචි කළ ආධාර සහ ගමන් මාර්ග ගමනාන්ත වැනි කැමති nfc ගෙවීම් සේවා තොරතුරු ලබා ගැනීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ආසන්න ක්ෂේත්ර සන්නිවේදනය පාලනය කරන්න"</string>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index aa23ee3..081f901 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -549,6 +549,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Umožňuje aplikácii zobrazovať reklamu v zariadeniach s rozhraním Bluetooth v okolí"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"určovať relatívnu polohu medzi zariadeniami so ultraširokopásmovým pripojením v okolí"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Povoľte aplikácii určovať relatívnu polohu medzi zariadeniami s ultraširokopásmovým pripojením v okolí"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcia so zariadeniami Wi-Fi v okolí"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Umožňuje aplikácii oznamovať a rozpoznávať relatívnu polohu zariadení Wi‑Fi v okolí a pripájať sa k nim"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferované informácie platenej služby NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikácii získavať preferované informácie platenej služby NFC, napríklad o registrovanej pomoci a trasách k cieľu."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ovládať technológiu NFC"</string>
@@ -732,6 +734,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Umožňuje aplikácii čítať a zapisovať konfiguráciu režimu bez vyrušení."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"spustenie používania povolenia na zobrazenie"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Umožňuje držiteľovi spustiť používanie povolenia aplikáciou. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"zobrazenie informácií o funkciách aplikácie"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Umožňuje držiteľovi zobraziť informácie o funkciách aplikácie."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"prístup k dátam senzorom s vysokou vzorkovacou frekvenciou"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Umožňuje aplikácii vzorkovať dáta senzorov s frekvenciou vyššou ako 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Nastaviť pravidlá pre heslo"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 17e1588..a6f8257 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -549,6 +549,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Aplikaciji dovoljuje oddajanje napravam Bluetooth v bližini."</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"določanje relativne oddaljenosti med napravami UWB v bližini"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikaciji dovoli, da določi relativno oddaljenost med napravami UWB v bližini."</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"komunikacijo z napravami Wi‑Fi v bližini"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Aplikaciji dovoljuje objavljanje in določanje relativnega položaja naprav Wi‑Fi v bližini ter povezovanje z njimi."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Podatki o prednostni storitvi za plačevanje prek povezave NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Aplikaciji omogoča pridobivanje podatkov o prednostni storitvi za plačevanje prek povezave NFC, kot so registrirani pripomočki in cilj preusmeritve."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"nadzor nad komunikacijo s tehnologijo bližnjega polja"</string>
@@ -732,6 +734,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Aplikaciji omogoča branje in pisanje konfiguracije načina »ne moti«."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"začetek uporabe dovoljenja za ogledovanje"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Imetniku omogoča začetek uporabe dovoljenj za aplikacijo. Nikoli ni potrebno za navadne aplikacije."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"začetek ogledovanja funkcij aplikacije"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Imetniku omogoča začetek ogledovanja informacij o funkcijah poljubne aplikacije."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"dostop do podatkov tipal z večjo hitrostjo vzorčenja"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Aplikaciji dovoljuje, da vzorči podatke tipal s hitrostjo, večjo od 200 Hz."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Nastavitev pravil za geslo"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 379aaf2..d42c91e 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Lejon që aplikacioni të reklamojë në pajisjet me Bluetooth në afërsi"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi me brezin ultra të gjerë"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Lejo që aplikacioni të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi me brezin ultra të gjerë"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"të ndërveprojë me pajisjet Wi-Fi në afërsi"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lejon që aplikacioni të reklamojë, të lidhet dhe të përcaktojë pozicionin relativ të pajisjeve Wi-Fi në afërsi"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacionet për shërbimin e preferuar të pagesës me NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lejon aplikacionin të marrë informacione për shërbimin e preferuar të pagesës me NFC si p.sh. ndihmat e regjistruara dhe destinacionin e itinerarit."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollo \"Komunikimin e fushës në afërsi\" NFC"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Lejon aplikacionin të lexojë dhe shkruajë konfigurimin e \"Mos shqetëso\"."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"nis përdorimin e lejes për shikimin"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Lejon që mbajtësi të nisë përdorimin e lejeve për një aplikacion. Nuk duhet të nevojitet asnjëherë për aplikacionet normale."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"fillojë shikimin e veçorive të aplikacionit"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Lejon që zotëruesi të fillojë të shikojë informacionin e veçorive për një aplikacion."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"qasu te të dhënat e sensorit me një shpejtësi kampionimi më të lartë"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Lejon aplikacionin të mbledhë shembujt e të dhënave të sensorit me shpejtësi më të lartë se 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Cakto rregullat e fjalëkalimit"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 823eae9..b04ddaf 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -546,6 +546,8 @@
<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>
@@ -729,6 +731,8 @@
<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_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>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 2785f90..357f98a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Tillåter appen att annonsera till Bluetooth-enheter i närheten"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"fastställa relativ position för Ultra Wideband-enheter i närheten"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tillåt att appen fastställer den relativa positionen mellan Ultra Wideband-enheter i närheten"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagera med wifi-enheter i närheten"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Tillåter appen att sända ut till, ansluta till och fastställa relativ position för wifi-enheter i närheten"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information kopplad till standardtjänsten för NFC-betalning"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillåter att appen hämtar information kopplad till standardtjänsten för NFC-betalning, till exempel registrerade hjälpmedel och ruttdestinationer."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollera närfältskommunikationen"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ger appen läs- och skrivbehörighet till konfigurationen för Stör ej."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"börja visa behörighetsanvändningen"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Gör att innehavaren kan öppna behörighetsanvändning för en app. Ska inte behövas för vanliga appar."</string>
+ <!-- no translation found for permlab_startViewAppFeatures (7955084203185903001) -->
+ <skip />
+ <!-- no translation found for permdesc_startViewAppFeatures (7207240860165206107) -->
+ <skip />
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"åtkomst till sensordata med en hög samplingsfrekvens"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Tillåter att appen får åtkomst till sensordata med en högre samplingsfrekvens än 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Ange lösenordsregler"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 72774ab..84daf98 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Huruhusu programu itangaze kwenye vifaa vyenye Bluetooth vilivyo karibu"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"kubainisha nafasi kati ya vifaa vyenye Bendi Pana Zaidi vilivyo karibu"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ruhusu programu ibainishe nafasi kati ya vifaa vyenye Bendi Pana Zaidi vilivyo karibu"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"tumia vifaa vya Wi‑Fi vilivyo karibu"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Huruhusu programu kutangaza, kuunganisha na kubaini mahali palipokadiriwa vilipo vifaa vya Wi-Fi vilivyo karibu"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maelezo ya Huduma Inayopendelewa ya Malipo ya NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Huruhusu programu kupata maelezo ya huduma inayopendelewa ya malipo ya nfc kama vile huduma zilizosajiliwa na njia."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kudhibiti Mawasiliano ya Vifaa Vilivyokaribu (NFC)"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Inaruhusu programu kusoma na kuandika usanidi wa kipengee cha Usinisumbue."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"anzisha kipengele cha kuona matumizi ya ruhusa"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Huruhusu kishikiliaji kuanzisha matumizi ya ruhusa ya programu. Haipaswi kuhitajika kwa ajili ya programu za kawaida."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"anzisha kipengele cha kuangalia vipengele vya programu"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Huruhusu mmiliki kuanza kuangalia maelezo ya vipengele vya programu."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"fikia data ya vitambuzi kwa kasi ya juu ya sampuli"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Huruhusu programu kujaribu sampuli ya data ya vitambuzi kwa kasi inayozidi Hz 200"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Kuweka kanuni za nenosiri"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 8f8325a..6e4148d 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"அருகிலுள்ள புளூடூத் சாதனங்களுக்குத் தெரியப்படுத்த ஆப்ஸை அனுமதிக்கும்"</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">"அருகிலுள்ள வைஃபை சாதனங்களுடன் தொடர்பில் இருக்கும்"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"அருகிலுள்ள வைஃபை சாதனங்களைத் தெரியப்படுத்தவும் இணைக்கவும் இருப்பிடத்தைத் தீர்மானிக்கவும் இது ஆப்ஸை அனுமதிக்கும்"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்கள்"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"பதிவுசெய்யப்பட்ட கருவிகள், சேருமிடத்திற்கான வழி போன்ற விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்களைப் பெற ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"குறுகிய இடைவெளி தகவல்பரிமாற்றத்தைக் கட்டுப்படுத்துதல்"</string>
@@ -726,6 +728,8 @@
<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_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 ஹெர்ட்ஸ்க்கும் அதிகமான வீதத்தில் சென்சார் தரவை மாதிரியாக்க ஆப்ஸை அனுமதிக்கும்"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"கடவுச்சொல் விதிகளை அமைக்கவும்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index c216de3..c3e5a66 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -432,7 +432,7 @@
<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="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>
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"సమీపంలోని బ్లూటూత్ పరికరాలలో అడ్వర్టయిజ్ చేయడానికి యాప్కు అనుమతిని ఇస్తుంది"</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">"సమీపంలోని Wi-Fi పరికరాలతో ఇంటరాక్ట్ చేస్తుంది"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"అడ్వర్టయిజ్, కనెక్ట్ చేయడానికి, సమీపంలోని Wi-Fi పరికరాల సంబంధిత పొజిషన్ను నిర్ణయించడానికి యాప్ను అనుమతిస్తుంది"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారం"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారాన్ని, అంటే రిజిస్టర్ చేయబడిన సహాయక సాధనాలు, మార్గం, గమ్యస్థానం వంటి వాటిని పొందేందుకు యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"సమీప క్షేత్ర కమ్యూనికేషన్ను నియంత్రించడం"</string>
@@ -726,6 +728,8 @@
<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_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>
@@ -933,7 +937,7 @@
<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_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>
@@ -1673,7 +1677,7 @@
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"పిన్ కోడ్లు సరిపోలలేదు"</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_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>
@@ -1688,9 +1692,9 @@
<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_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">"తీసివేయి"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"వాల్యూమ్ను సిఫార్సు చేయబడిన స్థాయి కంటే ఎక్కువగా పెంచాలా?\n\nసుదీర్ఘ వ్యవధుల పాటు అధిక వాల్యూమ్లో వినడం వలన మీ వినికిడి శక్తి దెబ్బ తినవచ్చు."</string>
@@ -2056,7 +2060,7 @@
<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="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>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 986f64d..207e522 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"อนุญาตให้แอปประกาศไปยังอุปกรณ์บลูทูธใกล้เคียง"</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">"โต้ตอบกับอุปกรณ์ Wi-Fi ที่อยู่ใกล้เคียง"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"อนุญาตให้แอปแสดงข้อมูล เชื่อมต่อ และระบุตำแหน่งซึ่งสัมพันธ์กับอุปกรณ์ Wi-Fi ที่อยู่ใกล้เคียง"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ข้อมูลบริการชำระเงิน NFC ที่ต้องการ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"อนุญาตให้แอปรับข้อมูลบริการชำระเงิน NFC ที่ต้องการ เช่น รหัสแอป (AID) ที่ลงทะเบียนและปลายทางของเส้นทาง"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ควบคุม Near Field Communication"</string>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 8ace595..e99f0c4 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Nagbibigay-daan sa app na mag-advertise sa mga kalapit na Bluetooth device"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"tukuyin ang relatibong posisyon sa pagitan ng mga kalapit na Ultra-Wideband device"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Payagan ang app na tukuyin ang relatibong posisyon sa pagitan ng mga kalapit na Ultra-Wideband device"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"makipag-ugnayan sa mga kalapit na Wi‑Fi device"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Nagbibigay-daan sa app na i-advertise, kumonekta sa, at tukuyin ang nauugnay na posisyon ng mga kalapit na Wi‑Fi device"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Impormasyon sa Gustong NFC na Serbisyo sa Pagbabayad"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pinapayagan ang app na makakuha ng impormasyon sa gustong nfc na serbisyo sa pagbabayad tulad ng mga nakarehistrong application ID at destinasyon ng ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolin ang Near Field Communication"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Nagbibigay-daan sa app na basahin at isulat ang configuration ng Huwag Istorbohin."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"simulan ang paggamit sa pahintulot sa pagtingin"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Binibigyang-daan ang may hawak na simulan ang paggamit ng pahintulot para sa isang app. Hindi dapat kailanganin kailanman para sa mga normal na app."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"simulang tingnan ang mga feature ng app"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Nagbibigay-daan sa may hawak na simulang tingnan ang impormasyon ng mga feature para sa isang app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"mag-access ng data ng sensor sa mataas na rate ng pag-sample"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Pinapahintulutan ang app na mag-sample ng data ng sensor sa rate na higit sa 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Magtakda ng mga panuntunan sa password"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 52614a8..b3f15a2 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Uygulamaya, yakındaki Bluetooth cihazlara reklam yayınlama izni verir"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"yakındaki Ultra Geniş Bant cihazların birbirine göre konumunu bul"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Uygulamanın, yakındaki Ultra Geniş Bant cihazların birbirine göre konumunu belirlemesine izin verin"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"yakındaki kablosuz cihazlarla etkileşim kurma"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Uygulamanın reklam sunmasına, bağlanmasına ve yakındaki kablosuz cihazların göreli konumunu belirlemesine izin verir"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tercih Edilen NFC Ödeme Hizmeti Bilgileri"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Uygulamaya, kayıtlı yardımlar ve rota hedefi gibi tercih edilen NFC ödeme hizmeti bilgilerini alma izni verir."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Yakın Alan İletişimini denetle"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Uygulamaya, Rahatsız Etmeyin yapılandırmasını okuma ve yazma izni verir."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"izin kullanımı görüntülemeye başlama"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"İzin sahibinin bir uygulama için izin kullanımı başlatmasına olanak tanır. Normal uygulamalar için hiçbir zaman kullanılmamalıdır."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"uygulama özelliklerini görüntülemeye başlama"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"İzin sahibinin, bir uygulamanın özellik bilgilerini görüntülemeye başlamasına izin verir."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"sensör verilerine daha yüksek örnekleme hızında eriş"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Uygulamanın, sensör verilerini 200 Hz\'den daha yüksek bir hızda örneklemesine olanak tanır"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Şifre kuralları ayarla"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 934c51d..7fb0b7b 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -549,6 +549,8 @@
<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">"взаємодіяти з пристроями Wi‑Fi поблизу"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Додаток може виявляти пристрої Wi‑Fi поблизу, підключатися до них і визначати їх відносне розташування"</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>
@@ -732,6 +734,8 @@
<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_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 Гц"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Устан. правила пароля"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 60f086b..9621b95 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"اس سے ایپ کو قریبی بلوٹوتھ آلات پر تشہیر کرنے کی اجازت ملتی ہے"</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">"قریبی Wi-Fi آلات کے ساتھ تعامل کریں"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ایپ کو اشتہار دینے، منسلک کرنے اور قریبی Wi-Fi آلات کی متعلقہ پوزیشن کا تعین کرنے کی اجازت دیتا ہے"</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 کمیونیکیشن کنٹرول کریں"</string>
@@ -726,6 +728,8 @@
<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_startViewAppFeatures" msgid="7955084203185903001">"ایپ کی خصوصیات کا ملاحظہ شروع کریں"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"ہولڈر کو ایپ کے لیے خصوصیات کی معلومات دیکھنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"نمونہ کاری کی اعلی شرح پر سینسر کے ڈیٹا تک رسائی حاصل کریں"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"ایپ کو Hz200 سے زیادہ شرح پر سینسر ڈیٹا کا نمونہ لینے کی اجازت دیتی ہے"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"پاس ورڈ کے اصول سیٹ کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index d4e2fcb..3d98dab 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Ilovaga yaqin-atrofdagi Bluetooth qurilmalariga reklama yuborish imkonini beradi"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"yaqin atrofdagi ultra keng polosali qurilmalarining nisbiy joylashishini aniqlash"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ilovaga yaqin atrofdagi ultra keng polosali qurilmalarining nisbiy joylashishini aniqlashga ruxsat beradi"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Yaqin-atrofdagi Wi-Fi qurilmalari bilan ishlash"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Ilovaga yaqin-atrofdagi Wi-Fi qurilmalarga reklama yuborish, ulanish va taxminiy joylashuvini aniqlash imkonini beradi."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Asosiy NFC toʻlov xizmati haqidagi axborot"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Bu ilovaga asosiy NFC toʻlov xizmati haqidagi axborotni olish imkonini beradi (masalan, qayd qilingan AID identifikatorlari va marshrutning yakuniy manzili)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC modulini boshqarish"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"“Bezovta qilinmasin” rejimi sozlamalarini ko‘rish va o‘zgartirish."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"foydalaniladigan ruxsatlar axborotini ochish"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Ilova foydalanadigan ruxsatlar axborotini ishga tushirishga ruxsat beradi. Oddiy ilovalar uchun talab qilinmaydi."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"ilova funksiyalari axborotini koʻrish"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Qurilma egasiga ilova funksiyalari axborotini koʻrishga ruxsat beradi."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"yuqori diskretlash chastotali sensor axborotiga ruxsat"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Ilova sensor axborotini 200 Hz dan yuqori tezlikda hisoblashi mumkin"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Parol qoidalarini o‘rnatish"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 872a175..052a658 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Cho phép ứng dụng quảng cáo trên các thiết bị Bluetooth ở gần"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Cho phép ứng dụng xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"tương tác với các thiết bị Wi‑Fi lân cận"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Cho phép ứng dụng thông báo, kết nối và xác định vị trí tương đối của các thiết bị Wi‑Fi lân cận"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần (NFC) được ưu tiên"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Cho phép ứng dụng nhận thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần mà bạn ưu tiên, chẳng hạn như các hình thức hỗ trợ đã đăng ký và điểm đến trong hành trình."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kiểm soát Liên lạc trường gần"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Cho phép ứng dụng đọc và ghi cấu hình Không làm phiền."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"cấp quyền xem"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Cho phép chủ sở hữu cấp quyền cho một ứng dụng. Các ứng dụng thông thường sẽ không bao giờ cần quyền này."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"bắt đầu xem các tính năng của ứng dụng"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Cho phép chủ sở hữu bắt đầu xem thông tin về tính năng của một ứng dụng."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"truy cập vào dữ liệu cảm biến ở tốc độ lấy mẫu cao"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Cho phép ứng dụng lấy mẫu dữ liệu cảm biến ở tốc độ lớn hơn 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Đặt quy tắc mật khẩu"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 8bbcf69..2dd9d6b 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"允许该应用向附近的蓝牙设备广播"</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">"与附近的 WLAN 设备互动"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允许该应用向附近的 WLAN 设备进行广播、连接到这些设备以及确定这些设备的相对位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首选 NFC 付款服务信息"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允许应用获取首选 NFC 付款服务信息,例如注册的应用标识符和路线目的地。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距离通信"</string>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 7c276a5..7a220a4 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"允許應用程式向附近的藍牙裝置宣傳"</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">"與附近的 Wi‑Fi 裝置互動"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允許應用程式顯示附近 Wi-Fi 裝置的資料、與其連接並判斷其相對位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"由用戶允許授權的 NFC 付款服務資訊"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得由用戶允許授權的 NFC 付款服務資訊 (如已註冊的付款輔助功能和最終付款對象)。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -726,6 +728,8 @@
<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_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>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index afc1392..d7db7ed 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -543,6 +543,10 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"允許應用程式向附近的藍牙裝置廣播"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"判斷附近超寬頻裝置間的相對位置"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置間的相對位置"</string>
+ <!-- no translation found for permlab_nearby_wifi_devices (392774237063608500) -->
+ <skip />
+ <!-- no translation found for permdesc_nearby_wifi_devices (3054307728646332906) -->
+ <skip />
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首選 NFC 付費服務資訊"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得首選 NFC 付費服務資訊,例如已註冊的輔助工具和路線目的地。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -726,6 +730,8 @@
<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_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>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 2e3c20b..518a45f 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -543,6 +543,8 @@
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Ivumela i-app ikhangise kumadivayisi e-Bluetooth aseduze"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"nquma indawo ehambelanayo phakathi kwamadivayisi e-Ultra-Wideband aseduze"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Vumela i-app inqume indawo ehambelanayo phakathi kwamadivayisi e-Ultra-Wideband aseduze"</string>
+ <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"xhumana namadivayisi we-Wi‑Fi aseduze"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Ivumela i-app ikhangise, ixhume, futhi inqume isimo esihambisanayo samadivayisi we-Wi-Fi aseduze"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ulwazi Lwesevisi Yenkokhelo Ye-NFC Okhethwayo"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ivuemela uhlelo lokusebenza ukuthola ulwazi lesevisi yenkokhelo ye-nfc njengezinsiza zokubhalisa nezindawo zomzila."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"lawula Uxhumano Lwenkambu Eseduze"</string>
@@ -726,6 +728,8 @@
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ivumela izinhlelo zokusebenza ukufunda nokubhala ukulungiswa kokuthi Ungaphazamisi."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"qala ukusetshenziswa kokubuka imvume"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Ivumela umphathi ukuthi aqale ukusetshenziswa kwemvume kohlelo lokusebenza. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+ <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"qala ukubuka izakhi ze-app"</string>
+ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Vumela isibambi ukuthi siqale ukubuka ulwazi lwezakhi lwe-app."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"finyelela idatha yenzwa ngenani eliphezulu lokwenza isampuli"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Ivumela uhlelo lokusebenza lusampule idatha yenzwa ngenani elikhulu kuno-200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Misa imithetho yephasiwedi"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b063140..74ce8f2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2352,10 +2352,6 @@
<!-- Type of the ambient tap sensor per device posture (defined by WM Jetpack posture).
Unspecified values use config_dozeTapSensor -->
<string-array name="config_dozeTapSensorPostureMapping" translatable="false">
- <item></item> <!-- UNKNOWN -->
- <item></item> <!-- CLOSED -->
- <item></item> <!-- HALF_OPENED -->
- <item></item> <!-- OPENED -->
</string-array>
<!-- Type of the long press sensor. Empty if long press is not supported. -->
diff --git a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
index 109b7ab..76c9f88 100644
--- a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
+++ b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
@@ -23,6 +23,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -54,6 +55,7 @@
private final Context mMockContext = mock(Context.class);
@Mock
private Context mRealContext;
+ @Mock
private PackageManager mPm;
private static final String PKG = "com.example.o";
@@ -78,6 +80,7 @@
InstrumentationRegistry.getContext().getResources());
when(mMockContext.getPackageManager()).thenReturn(mPm);
when(mMockContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
+ when(mPm.getApplicationLabel(any())).thenReturn("");
mRealContext = InstrumentationRegistry.getContext();
}
@@ -217,6 +220,26 @@
assertEquals(pkg, resultContext.getPackageName());
}
+ @Test
+ public void testGetUidFromKey() {
+ StatusBarNotification sbn = getNotification("pkg", null, "channel");
+
+ assertEquals(UID, StatusBarNotification.getUidFromKey(sbn.getKey()));
+
+ sbn.setOverrideGroupKey("addsToKey");
+ assertEquals(UID, StatusBarNotification.getUidFromKey(sbn.getKey()));
+ }
+
+ @Test
+ public void testGetPkgFromKey() {
+ StatusBarNotification sbn = getNotification("pkg", null, "channel");
+
+ assertEquals("pkg", StatusBarNotification.getPkgFromKey(sbn.getKey()));
+
+ sbn.setOverrideGroupKey("addsToKey");
+ assertEquals("pkg", StatusBarNotification.getPkgFromKey(sbn.getKey()));
+ }
+
private StatusBarNotification getNotification(String pkg, String group, String channelId) {
return getNotification(pkg, getNotificationBuilder(group, channelId));
}
diff --git a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
index 4779786..9696fdf 100644
--- a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
+++ b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
@@ -28,7 +28,7 @@
import static androidx.test.espresso.matcher.ViewMatchers.withTagValue;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
-import static com.android.internal.widget.FloatingToolbar.MenuItemRepr;
+import static com.android.internal.widget.FloatingToolbarPopup.MenuItemRepr;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
index 9713962..8a50f22 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
@@ -144,7 +144,7 @@
mediaControlFilter.addAction(ACTION_NEXT);
mediaControlFilter.addAction(ACTION_PREV);
mContext.registerReceiverForAllUsers(mMediaActionReceiver, mediaControlFilter,
- SYSTEMUI_PERMISSION, mainHandler);
+ SYSTEMUI_PERMISSION, mainHandler, Context.RECEIVER_EXPORTED);
// Creates the standard media buttons that we may show.
mPauseAction = getDefaultRemoteAction(R.string.pip_pause,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index ec71fbe..3b75bfb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -215,10 +215,12 @@
options = mStageCoordinator.resolveStartStage(stage, position, options, null /* wct */);
try {
+ final WindowContainerTransaction evictWct = new WindowContainerTransaction();
+ mStageCoordinator.prepareEvictChildTasks(position, evictWct);
final int result =
ActivityTaskManager.getService().startActivityFromRecents(taskId, options);
if (result == START_SUCCESS || result == START_TASK_TO_FRONT) {
- mStageCoordinator.evictOccludedChildren(position);
+ mSyncQueue.queue(evictWct);
}
} catch (RemoteException e) {
Slog.e(TAG, "Failed to launch task", e);
@@ -229,13 +231,15 @@
@SplitScreen.StageType int stage, @SplitPosition int position,
@Nullable Bundle options, UserHandle user) {
options = mStageCoordinator.resolveStartStage(stage, position, options, null /* wct */);
+ final WindowContainerTransaction evictWct = new WindowContainerTransaction();
+ mStageCoordinator.prepareEvictChildTasks(position, evictWct);
try {
LauncherApps launcherApps =
mContext.getSystemService(LauncherApps.class);
launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */,
options, user);
- mStageCoordinator.evictOccludedChildren(position);
+ mSyncQueue.queue(evictWct);
} catch (ActivityNotFoundException e) {
Slog.e(TAG, "Failed to launch shortcut", e);
}
@@ -255,6 +259,9 @@
private void startIntentLegacy(PendingIntent intent, Intent fillInIntent,
@SplitScreen.StageType int stage, @SplitPosition int position,
@Nullable Bundle options) {
+ final WindowContainerTransaction evictWct = new WindowContainerTransaction();
+ mStageCoordinator.prepareEvictChildTasks(position, evictWct);
+
LegacyTransitions.ILegacyTransition transition = new LegacyTransitions.ILegacyTransition() {
@Override
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
@@ -280,12 +287,11 @@
}
}
- // Launching a new app into a specific split evicts tasks previously in the same
- // split.
- mStageCoordinator.evictOccludedChildren(position);
+ mSyncQueue.queue(evictWct);
}
};
- WindowContainerTransaction wct = new WindowContainerTransaction();
+
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
options = mStageCoordinator.resolveStartStage(stage, position, options, wct);
wct.sendPendingIntent(intent, fillInIntent, options);
mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
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 0cff18e..72d9880 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
@@ -394,10 +394,16 @@
TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, wct, remoteTransition, this);
}
- void evictOccludedChildren(@SplitPosition int position) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- (position == mSideStagePosition ? mSideStage : mMainStage).evictOccludedChildren(wct);
- mTaskOrganizer.applyTransaction(wct);
+ /**
+ * Collects all the current child tasks of a specific split and prepares transaction to evict
+ * them to display.
+ */
+ void prepareEvictChildTasks(@SplitPosition int position, WindowContainerTransaction wct) {
+ if (position == mSideStagePosition) {
+ mSideStage.evictAllChildren(wct);
+ } else {
+ mMainStage.evictAllChildren(wct);
+ }
}
Bundle resolveStartStage(@SplitScreen.StageType int stage,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 071badf..6f1a09d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -248,12 +248,11 @@
wct.reorder(mChildrenTaskInfo.get(taskId).token, onTop /* onTop */);
}
- void evictOccludedChildren(WindowContainerTransaction wct) {
+ /** Collects all the current child tasks and prepares transaction to evict them to display. */
+ void evictAllChildren(WindowContainerTransaction wct) {
for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
- if (!taskInfo.isVisible) {
- wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
- }
+ wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
index a5746a4..3ed72e2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
@@ -21,6 +21,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
@@ -31,6 +33,7 @@
import android.os.SystemProperties;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
+import android.window.WindowContainerTransaction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -50,7 +53,7 @@
/**
* Tests for {@link StageTaskListener}
* Build/Install/Run:
- * atest WMShellUnitTests:StageTaskListenerTests
+ * atest WMShellUnitTests:StageTaskListenerTests
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -58,11 +61,16 @@
private static final boolean ENABLE_SHELL_TRANSITIONS =
SystemProperties.getBoolean("persist.debug.shell_transit", false);
- @Mock private ShellTaskOrganizer mTaskOrganizer;
- @Mock private StageTaskListener.StageListenerCallbacks mCallbacks;
- @Mock private SyncTransactionQueue mSyncQueue;
- @Mock private StageTaskUnfoldController mStageTaskUnfoldController;
- @Captor private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
+ @Mock
+ private ShellTaskOrganizer mTaskOrganizer;
+ @Mock
+ private StageTaskListener.StageListenerCallbacks mCallbacks;
+ @Mock
+ private SyncTransactionQueue mSyncQueue;
+ @Mock
+ private StageTaskUnfoldController mStageTaskUnfoldController;
+ @Captor
+ private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
private SurfaceSession mSurfaceSession = new SurfaceSession();
private SurfaceControl mSurfaceControl;
private ActivityManager.RunningTaskInfo mRootTask;
@@ -167,4 +175,18 @@
mStageTaskListener.onTaskInfoChanged(childTask);
verify(mCallbacks).onNoLongerSupportMultiWindow();
}
+
+ @Test
+ public void testEvictAllChildren() {
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ mStageTaskListener.evictAllChildren(wct);
+ assertTrue(wct.isEmpty());
+
+ final ActivityManager.RunningTaskInfo childTask =
+ new TestRunningTaskInfoBuilder().setParentTaskId(mRootTask.taskId).build();
+ mStageTaskListener.onTaskAppeared(childTask, mSurfaceControl);
+
+ mStageTaskListener.evictAllChildren(wct);
+ assertFalse(wct.isEmpty());
+ }
}
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 83bc38b2..1077275 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -158,18 +158,10 @@
* the user supplied callback method OnErrorListener.onError() will be
* invoked by the internal player engine and the object will be
* transfered to the <em>Error</em> state. </li>
- * <li>It is also recommended that once
- * a MediaPlayer object is no longer being used, call {@link #release()} immediately
- * so that resources used by the internal player engine associated with the
- * MediaPlayer object can be released immediately. Resource may include
- * singleton resources such as hardware acceleration components and
- * failure to call {@link #release()} may cause subsequent instances of
- * MediaPlayer objects to fallback to software implementations or fail
- * altogether. Once the MediaPlayer
- * object is in the <em>End</em> state, it can no longer be used and
- * there is no way to bring it back to any other state. </li>
- * <li>Furthermore,
- * the MediaPlayer objects created using <code>new</code> is in the
+ * <li>You must call {@link #release()} once you have finished using an instance to release
+ * acquired resources, such as memory and codecs. Once you have called {@link #release}, you
+ * must no longer interact with the released instance.
+ * <li>MediaPlayer objects created using <code>new</code> is in the
* <em>Idle</em> state, while those created with one
* of the overloaded convenient <code>create</code> methods are <em>NOT</em>
* in the <em>Idle</em> state. In fact, the objects are in the <em>Prepared</em>
@@ -407,7 +399,7 @@
* <tr><td>release </p></td>
* <td>any </p></td>
* <td>{} </p></td>
- * <td>After {@link #release()}, the object is no longer available. </p></td></tr>
+ * <td>After {@link #release()}, you must not interact with the object. </p></td></tr>
* <tr><td>reset </p></td>
* <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
* PlaybackCompleted, Error}</p></td>
@@ -657,11 +649,13 @@
private ProvisioningThread mDrmProvisioningThread;
/**
- * Default constructor. Consider using one of the create() methods for
- * synchronously instantiating a MediaPlayer from a Uri or resource.
- * <p>When done with the MediaPlayer, you should call {@link #release()},
- * to free the resources. If not released, too many MediaPlayer instances may
- * result in an exception.</p>
+ * Default constructor.
+ *
+ * <p>Consider using one of the create() methods for synchronously instantiating a MediaPlayer
+ * from a Uri or resource.
+ *
+ * <p>You must call {@link #release()} when you are finished using the instantiated instance.
+ * Doing so frees any resources you have previously acquired.
*/
public MediaPlayer() {
this(AudioSystem.AUDIO_SESSION_ALLOCATE);
@@ -873,9 +867,10 @@
/**
* Convenience method to create a MediaPlayer for a given Uri.
* On success, {@link #prepare()} will already have been called and must not be called again.
- * <p>When done with the MediaPlayer, you should call {@link #release()},
- * to free the resources. If not released, too many MediaPlayer instances will
- * result in an exception.</p>
+ *
+ * <p>You must call {@link #release()} when you are finished using the created instance. Doing
+ * so frees any resources you have previously acquired.
+ *
* <p>Note that since {@link #prepare()} is called automatically in this method,
* you cannot change the audio
* session ID (see {@link #setAudioSessionId(int)}) or audio attributes
@@ -892,9 +887,10 @@
/**
* Convenience method to create a MediaPlayer for a given Uri.
* On success, {@link #prepare()} will already have been called and must not be called again.
- * <p>When done with the MediaPlayer, you should call {@link #release()},
- * to free the resources. If not released, too many MediaPlayer instances will
- * result in an exception.</p>
+ *
+ * <p>You must call {@link #release()} when you are finished using the created instance. Doing
+ * so frees any resources you have previously acquired.
+ *
* <p>Note that since {@link #prepare()} is called automatically in this method,
* you cannot change the audio
* session ID (see {@link #setAudioSessionId(int)}) or audio attributes
@@ -955,9 +951,10 @@
/**
* Convenience method to create a MediaPlayer for a given resource id.
* On success, {@link #prepare()} will already have been called and must not be called again.
- * <p>When done with the MediaPlayer, you should call {@link #release()},
- * to free the resources. If not released, too many MediaPlayer instances will
- * result in an exception.</p>
+ *
+ * <p>You must call {@link #release()} when you are finished using the created instance. Doing
+ * so frees any resources you have previously acquired.
+ *
* <p>Note that since {@link #prepare()} is called automatically in this method,
* you cannot change the audio
* session ID (see {@link #setAudioSessionId(int)}) or audio attributes
@@ -2157,21 +2154,8 @@
/**
* Releases resources associated with this MediaPlayer object.
- * It is considered good practice to call this method when you're
- * done using the MediaPlayer. In particular, whenever an Activity
- * of an application is paused (its onPause() method is called),
- * or stopped (its onStop() method is called), this method should be
- * invoked to release the MediaPlayer object, unless the application
- * has a special need to keep the object around. In addition to
- * unnecessary resources (such as memory and instances of codecs)
- * being held, failure to call this method immediately if a
- * MediaPlayer object is no longer needed may also lead to
- * continuous battery consumption for mobile devices, and playback
- * failure for other applications if no multiple instances of the
- * same codec are supported on a device. Even if multiple instances
- * of the same codec are supported, some performance degradation
- * may be expected when unnecessary multiple instances are used
- * at the same time.
+ *
+ * <p>You must call this method once the instance is no longer required.
*/
public void release() {
baseRelease();
diff --git a/media/java/android/media/tv/BroadcastInfoRequest.aidl b/media/java/android/media/tv/BroadcastInfoRequest.aidl
new file mode 100644
index 0000000..26cdcc5
--- /dev/null
+++ b/media/java/android/media/tv/BroadcastInfoRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 android.media.tv;
+
+parcelable BroadcastInfoRequest;
diff --git a/media/java/android/media/tv/BroadcastInfoRequest.java b/media/java/android/media/tv/BroadcastInfoRequest.java
new file mode 100644
index 0000000..6077f04
--- /dev/null
+++ b/media/java/android/media/tv/BroadcastInfoRequest.java
@@ -0,0 +1,58 @@
+/*
+ * 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 android.media.tv;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import android.annotation.NonNull;
+
+/** @hide */
+public final class BroadcastInfoRequest implements Parcelable {
+ public static final @NonNull Parcelable.Creator<BroadcastInfoRequest> CREATOR =
+ new Parcelable.Creator<BroadcastInfoRequest>() {
+ @Override
+ public BroadcastInfoRequest createFromParcel(Parcel source) {
+ return new BroadcastInfoRequest(source);
+ }
+
+ @Override
+ public BroadcastInfoRequest[] newArray(int size) {
+ return new BroadcastInfoRequest[size];
+ }
+ };
+
+ int requestId;
+
+ public BroadcastInfoRequest(int requestId) {
+ this.requestId = requestId;
+ }
+
+ private BroadcastInfoRequest(Parcel source) {
+ requestId = source.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(requestId);
+ }
+}
diff --git a/media/java/android/media/tv/BroadcastInfoResponse.aidl b/media/java/android/media/tv/BroadcastInfoResponse.aidl
new file mode 100644
index 0000000..65e65b2
--- /dev/null
+++ b/media/java/android/media/tv/BroadcastInfoResponse.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 android.media.tv;
+
+parcelable BroadcastInfoResponse;
diff --git a/media/java/android/media/tv/BroadcastInfoResponse.java b/media/java/android/media/tv/BroadcastInfoResponse.java
new file mode 100644
index 0000000..64c884e
--- /dev/null
+++ b/media/java/android/media/tv/BroadcastInfoResponse.java
@@ -0,0 +1,58 @@
+/*
+ * 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 android.media.tv;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import android.annotation.NonNull;
+
+/** @hide */
+public final class BroadcastInfoResponse implements Parcelable {
+ public static final @NonNull Parcelable.Creator<BroadcastInfoResponse> CREATOR =
+ new Parcelable.Creator<BroadcastInfoResponse>() {
+ @Override
+ public BroadcastInfoResponse createFromParcel(Parcel source) {
+ return new BroadcastInfoResponse(source);
+ }
+
+ @Override
+ public BroadcastInfoResponse[] newArray(int size) {
+ return new BroadcastInfoResponse[size];
+ }
+ };
+
+ int requestId;
+
+ public BroadcastInfoResponse(int requestId) {
+ this.requestId = requestId;
+ }
+
+ private BroadcastInfoResponse(Parcel source) {
+ requestId = source.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(requestId);
+ }
+}
diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl
index 72f8b57..5dad633 100644
--- a/media/java/android/media/tv/ITvInputClient.aidl
+++ b/media/java/android/media/tv/ITvInputClient.aidl
@@ -22,6 +22,7 @@
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
import android.view.InputChannel;
+import android.media.tv.BroadcastInfoResponse;
/**
* Interface a client of the ITvInputManager implements, to identify itself and receive information
@@ -48,4 +49,7 @@
void onTuned(int seq, in Uri channelUri);
void onRecordingStopped(in Uri recordedProgramUri, int seq);
void onError(int error, int seq);
+
+ // For broadcast info
+ void onBroadcastInfoResponse(in BroadcastInfoResponse response, int seq);
}
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index d8d1ba13..eaf89ba 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -35,6 +35,7 @@
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.view.Surface;
+import android.media.tv.BroadcastInfoRequest;
/**
* Interface to the TV input manager service.
@@ -97,6 +98,9 @@
void pauseRecording(in IBinder sessionToken, in Bundle params, int userId);
void resumeRecording(in IBinder sessionToken, in Bundle params, int userId);
+ // For broadcast info
+ void requestBroadcastInfo(in IBinder sessionToken, in BroadcastInfoRequest request, int userId);
+
// For TV input hardware binding
List<TvInputHardwareInfo> getHardwareList();
ITvInputHardware acquireTvInputHardware(int deviceId, in ITvInputHardwareCallback callback,
diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
index 158cf21..1eab650 100644
--- a/media/java/android/media/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -22,6 +22,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.view.Surface;
+import android.media.tv.BroadcastInfoRequest;
/**
* Sub-interface of ITvInputService which is created per session and has its own context.
@@ -60,4 +61,7 @@
void stopRecording();
void pauseRecording(in Bundle params);
void resumeRecording(in Bundle params);
+
+ // For broadcast info
+ void requestBroadcastInfo(in BroadcastInfoRequest request);
}
diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl
index af76f90..d857c00 100644
--- a/media/java/android/media/tv/ITvInputSessionCallback.aidl
+++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl
@@ -20,6 +20,7 @@
import android.net.Uri;
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
+import android.media.tv.BroadcastInfoResponse;
/**
* Helper interface for ITvInputSession to allow the TV input to notify the system service when a
@@ -45,4 +46,7 @@
void onTuned(in Uri channelUri);
void onRecordingStopped(in Uri recordedProgramUri);
void onError(int error);
+
+ // For broadcast info
+ void onBroadcastInfoResponse(in BroadcastInfoResponse response);
}
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index abccf8d..4257145 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -70,6 +70,7 @@
private static final int DO_STOP_RECORDING = 21;
private static final int DO_PAUSE_RECORDING = 22;
private static final int DO_RESUME_RECORDING = 23;
+ private static final int DO_REQUEST_BROADCAST_INFO = 24;
private final boolean mIsRecordingSession;
private final HandlerCaller mCaller;
@@ -234,6 +235,10 @@
mTvInputRecordingSessionImpl.resumeRecording((Bundle) msg.obj);
break;
}
+ case DO_REQUEST_BROADCAST_INFO: {
+ mTvInputSessionImpl.requestBroadcastInfo((BroadcastInfoRequest) msg.obj);
+ break;
+ }
default: {
Log.w(TAG, "Unhandled message code: " + msg.what);
break;
@@ -383,6 +388,11 @@
mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_RESUME_RECORDING, params));
}
+ @Override
+ public void requestBroadcastInfo(BroadcastInfoRequest request) {
+ mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_REQUEST_BROADCAST_INFO, request));
+ }
+
private final class TvInputEventReceiver extends InputEventReceiver {
public TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 34e4609..f22b7dc 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -656,6 +656,13 @@
*/
void onError(Session session, @TvInputManager.RecordingError int error) {
}
+
+ /**
+ * @param session
+ * @param response
+ */
+ public void onBroadcastInfoResponse(Session session, BroadcastInfoResponse response) {
+ }
}
private static final class SessionCallbackRecord {
@@ -835,6 +842,15 @@
}
});
}
+
+ void postBroadcastInfoResponse(final BroadcastInfoResponse response) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mSessionCallback.onBroadcastInfoResponse(mSession, response);
+ }
+ });
+ }
}
/**
@@ -1233,6 +1249,18 @@
record.postError(error);
}
}
+
+ @Override
+ public void onBroadcastInfoResponse(BroadcastInfoResponse response, int seq) {
+ synchronized (mSessionCallbackRecordMap) {
+ SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+ if (record == null) {
+ Log.e(TAG, "Callback not found for seq " + seq);
+ return;
+ }
+ record.postBroadcastInfoResponse(response);
+ }
+ }
};
ITvInputManagerCallback managerCallback = new ITvInputManagerCallback.Stub() {
@Override
@@ -2839,6 +2867,19 @@
}
}
+ public void requestBroadcastInfo(BroadcastInfoRequest request) {
+ if (mToken == null) {
+ Log.w(TAG, "The session has been already released");
+ return;
+ }
+ try {
+ mService.requestBroadcastInfo(mToken, request, mUserId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ }
+
private final class InputEventHandler extends Handler {
public static final int MSG_SEND_INPUT_EVENT = 1;
public static final int MSG_TIMEOUT_INPUT_EVENT = 2;
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 77fb2b2..f312f64 100755
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -769,6 +769,29 @@
});
}
+ /**
+ * Notifies response for broadcast info.
+ *
+ * @param response
+ * @hide
+ */
+ public void notifyBroadcastInfoResponse(@NonNull final BroadcastInfoResponse response) {
+ executeOrPostRunnableOnMainThread(new Runnable() {
+ @MainThread
+ @Override
+ public void run() {
+ try {
+ if (DEBUG) Log.d(TAG, "notifyBroadcastInfoResponse");
+ if (mSessionCallback != null) {
+ mSessionCallback.onBroadcastInfoResponse(response);
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "error in notifyBroadcastInfoResponse", e);
+ }
+ }
+ });
+ }
+
private void notifyTimeShiftStartPositionChanged(final long timeMs) {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -917,6 +940,13 @@
public abstract void onSetStreamVolume(@FloatRange(from = 0.0, to = 1.0) float volume);
/**
+ * @param request broadcast info request
+ * @hide
+ */
+ public void onRequestBroadcastInfo(@NonNull BroadcastInfoRequest request) {
+ }
+
+ /**
* Tunes to a given channel.
*
* <p>No video will be displayed until {@link #notifyVideoAvailable()} is called.
@@ -1506,6 +1536,10 @@
}
}
+ void requestBroadcastInfo(BroadcastInfoRequest request) {
+ onRequestBroadcastInfo(request);
+ }
+
/**
* Takes care of dispatching incoming input events and tells whether the event was handled.
*/
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 51e954f..f3fb48f 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-oudio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD oudio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Gehoortoestelle"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Gekoppel aan gehoortoestelle"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Gekoppel aan LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Gekoppel aan media-oudio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Gekoppel aan foonoudio"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Gekoppel aan lêeroordragbediener"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Gebruik vir lêeroordrag"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Gebruik vir invoer"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gebruik vir gehoortoestelle"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Gebruik vir LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Bind saam"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"BIND SAAM"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Kanselleer"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index b0ce875..647d052 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"ኤችዲ ኦዲዮ፦ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"ኤችዲ ኦዲዮ"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"አጋዥ መስሚያዎች"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ከአጋዥ መስሚያዎች ጋር ተገናኝቷል"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"ከ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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index ba6bd70..662ffdd 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"صوت عالي الدقة: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"صوت عالي الدقة"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"سماعات الأذن الطبية"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"تمّ التوصيل بسماعات الأذن الطبية"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"متصل بـ 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index d0fb2d4..dfe708d 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -100,14 +100,14 @@
<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">"সক্ৰিয়, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> বেটাৰি, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$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">"সক্ৰিয়, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> বেটাৰী, R: <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">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> বেটাৰি, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$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> বেটাৰী, R: <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_profile_a2dp" msgid="4632426382762851724">"মিডিয়াৰ অডিঅ’"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"ফ\'ন কলসমূহ"</string>
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"এইচ্ছডি অডি\'অ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"এইচ্ছডি অডিঅ’"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"শ্ৰৱণ যন্ত্ৰ"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"শ্ৰৱণ যন্ত্ৰলৈ সংযোগ কৰা হৈছে"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
@@ -157,8 +160,8 @@
<string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"ব্লুটুথ"</string>
<string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"বাওঁফালৰ শ্ৰৱণ যন্ত্ৰটো যোৰ পতোৱা হৈছে…"</string>
<string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"সোঁফালৰ শ্ৰৱণ যন্ত্ৰটো যোৰ পতোৱা হৈছে…"</string>
- <string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰি বাকী আছে"</string>
- <string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"সোঁ - বেটাৰি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী বাকী আছে"</string>
+ <string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"সোঁ - বেটাৰী <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="accessibility_wifi_off" msgid="1195445715254137155">"ৱাই-ফাই অফ হৈ আছে।"</string>
<string name="accessibility_no_wifi" msgid="5297119459491085771">"ৱাইফাই সংযোগ বিচ্ছিন্ন হৈ আছে।"</string>
<string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"ৱাই-ফাই এদাল দণ্ড।"</string>
@@ -316,7 +319,7 @@
<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_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>
@@ -402,7 +405,7 @@
<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_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>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index d6c4c88..335e982e 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -122,7 +122,11 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Eşitmə cihazları"</string>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Eşitmə Aparatlarına qoşuldu"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Media audioya birləşdirilib"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Telefon audiosuna qoşulu"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Fayl transfer serverinə qoşulu"</string>
@@ -140,6 +144,8 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Fayl transferi üçün istifadə edin"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Daxiletmə üçün istifadə edin"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Eşitmə Aparatları üçün istifadə edin"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Qoşulsun"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"QOŞULSUN"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Ləğv edin"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index da65227..5af3006 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -122,7 +122,9 @@
<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_profile_le_audio" msgid="5158149987518342036">"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="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 3126f52..d1b6226 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Падключана да слыхавых апаратаў"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Падключана да 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 5a57d44..375879a 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Висококачествено аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Висококачествено аудио"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слухови апарати"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Установена е връзка със слухов апарат"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Свързано с(ъс) 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index bac2f36..2e614fa 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -122,7 +122,11 @@
<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>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"হিয়ারিং এডের সাথে কানেক্ট করা হয়েছে"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<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>
@@ -140,6 +144,8 @@
<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>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<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>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 483d3b6..e33978f 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni aparati"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Povezan na slušne aparate"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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 na zvuk telefona"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Povezano sa serverom za prijenos podataka"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Koristi za prijenos fajlova"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Koristi kao ulaz"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Korištenje za slušne aparate"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Koristi 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>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 1cffe78..2b10a30 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Àudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Àudio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audiòfons"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"S\'ha connectat als audiòfons"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Connectat a LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connectat a l\'àudio del mitjà"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Connectat a àudio del telèfon"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Connectat al servidor de transferència de fitxers"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Utilitza per a la transferència de fitxers"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Utilitza per a entrada"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Utilitza per als audiòfons"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Utilitza per a LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Vincula"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"VINCULA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancel·la"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index dd41dbc..7a94bb4 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -122,7 +122,9 @@
<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">"Naslouchátka"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Připojeno k naslouchátkům"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Připojeno k LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Připojeno ke zvukovému médiu"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Připojeno k náhlavní soupravě"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Připojeno k serveru pro přenos dat"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Použít pro přenos souborů"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Použít pro vstup"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Použít pro naslouchátka"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Používat pro LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Spárovat"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SPÁROVAT"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Zrušit"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index dde780a..ff5c6ae 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-lyd"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Høreapparater"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Forbundet til høreapparater"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Forbundet med LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Forbundet til medielyd"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Forbundet til telefonlyd"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Forbundet til filoverførselsserver"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Brug til filoverførsel"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Brug til input"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Brug til høreapparater"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Brug med LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Par"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ACCEPTÉR PARRING"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annuller"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 520ac98..a75d19b 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -122,7 +122,11 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-Audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-Audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hörhilfen"</string>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Mit Hörhilfen verbunden"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Verbunden mit Medien-Audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Verbunden mit Telefon-Audio"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Mit Dateiübertragungsserver verbunden"</string>
@@ -140,6 +144,8 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Für Dateiübertragung verwenden"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Für Eingabe verwenden"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Für Hörhilfen verwenden"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Koppeln"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"KOPPELN"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Abbrechen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index d95f5b5..402e489 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Έγινε σύνδεση σε βοηθήματα ακοής"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Συνδέθηκε σε 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 1273a19..fb3bc7a 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Connected to LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Connected to phone audio"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Connected to file-transfer server"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Use for file transfer"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Use for input"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Use for Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Use for LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Pair"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PAIR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancel"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 70fdaac..e33af37 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Connected to LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Connected to phone audio"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Connected to file-transfer server"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Use for file transfer"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Use for input"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Use for Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Use for LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Pair"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PAIR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancel"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 1273a19..fb3bc7a 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Connected to LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Connected to phone audio"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Connected to file-transfer server"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Use for file transfer"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Use for input"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Use for Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Use for LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Pair"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PAIR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancel"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 1273a19..fb3bc7a 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Connected to LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Connected to phone audio"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Connected to file-transfer server"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Use for file transfer"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Use for input"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Use for Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Use for LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Pair"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PAIR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancel"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 56267bb..2c58236 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Connected to LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Connected to phone audio"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Connected to file transfer server"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Use for file transfer"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Use for input"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Use for Hearing Aids"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Use for LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Pair"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PAIR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancel"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 30294ce..471e715 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio en HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audífonos"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a audífonos"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Conectado a LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado al audio multimedia"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Conectado al audio del dispositivo"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Conectado al servidor de transferencia de archivo"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Utilizar para la transferencia de archivos"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Utilizar para entrada"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Usar para audífonos"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Usar para LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Vincular"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SINCRONIZAR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index fbdb37a..f28d062 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audífonos"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a audífonos"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Conectado a LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado al audio del medio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Conectado al audio del teléfono"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Conectado con el servidor de transferencia de archivos"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Uso de la transferencia de archivos"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Usar para entrada"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Usar con audífonos"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Usar en LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Emparejar"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"EMPAREJAR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index ca83bf8..aaf3201 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-heli: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-heli"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Kuuldeaparaadid"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Kuuldeaparaatidega ühendatud"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Ühendatud üksusega LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ühendatud meediumiheliga"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Ühendatud telefoniheliga"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Ühendatud failiedastuse serveriga"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Kasutage failide edastamiseks"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Kasutage sisendi jaoks"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Kasuta kuulmisaparaatide puhul"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Üksuse LE_AUDIO kasutamine"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Seo"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SEO"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Tühista"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 915db9c..0f929de 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Kalitate handiko audioa: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Kalitate handiko audioa"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audifonoak"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Audifonoetara konektatuta"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Konektatu LE_AUDIO-ra"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Euskarriaren audiora konektatuta"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Telefonoaren audiora konektatuta"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Fitxategi-transferentziako zerbitzarira konektatuta"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Erabili fitxategi-transferentziarako"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Erabili idazketarako"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Erabili audifonoak"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Erabili LE_AUDIO-rako"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Parekatu"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PAREKATU"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Utzi"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 6ceea96..a5a11eb 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"به سمعک متصل شد"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"متصل به 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 57780e1..373f6a4 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-ääni: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-ääni"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Kuulolaitteet"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Yhdistetty kuulolaitteisiin"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"LE_AUDIO yhdistetty"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Yhdistetty median ääneen"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Yhdistetty puhelimen ääneen"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Yhdistetty tiedostonsiirtopalvelimeen"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Käytä tiedostojen siirtoon"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Käytä syöttöön"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Käytä kuulolaitteilla"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Käyttö: LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Muodosta laitepari"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"MUODOSTA LAITEPARI"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Peru"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index dbd3f71..b00ea16 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -122,7 +122,11 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Prothèses auditives"</string>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connecté aux prothèses auditives"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connecté aux paramètres audio du média"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Connecté à l\'audio du téléphone"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Connexion au serveur de transfert de fichiers"</string>
@@ -140,6 +144,8 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Utiliser pour le transfert de fichiers"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Utiliser comme entrée"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Utiliser avec les prothèses auditives"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Associer"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ASSOCIER"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annuler"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index ce00a30..5f635b0 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Appareils auditifs"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connexion établie avec les appareils auditifs"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Connecté à LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connecté aux paramètres audio du média"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Connecté aux paramètres audio du téléphone"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Connexion au serveur de transfert de fichiers"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Utiliser pour le transfert de fichiers"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Utiliser comme entrée"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Utiliser pour les appareils auditifs"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Utiliser pour LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Associer"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ASSOCIER"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annuler"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 7de607f..109cdc6 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -122,7 +122,11 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio en HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audiófonos"</string>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a audiófonos"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado ao audio multimedia"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Conectado ao audio do teléfono"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Conectado ao servidor de transferencia de ficheiros"</string>
@@ -140,6 +144,8 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Utilízase para a transferencia de ficheiros"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Utilízase para a entrada"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Utilizar para audiófonos"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Vincular"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"VINCULAR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index f8b1123..5bb68b7 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -122,7 +122,11 @@
<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>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"શ્રવણ યંત્રો સાથે કનેક્ટ કરેલું છે"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<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>
@@ -140,6 +144,8 @@
<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>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<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>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 0c115ca..fcf04bc 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"एचडी ऑडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"एचडी ऑडियो"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"कान की मशीन"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"सुनने में मदद करने वाले डिवाइस से कनेक्ट है"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index f671e8c..1ef94fb 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni aparati"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"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="3162538609379333442">"Povezano s profilom LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezano s medijskim zvukom"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Povezano sa telefonskim zvukom"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Povezano s poslužiteljem za prijenos datoteka"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Koristi za prijenos datoteke"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Upotrijebi za ulaz"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Upotrijebi za Slušne aparate"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Upotrebljavajte 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">"Odustani"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 3a703a9..deb0f81 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hallókészülékek"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Hallókészülékhez csatlakoztatva"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Csatlakoztatva ehhez: LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Csatlakoztatva az eszköz hangjához"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Csatlakoztatva a telefon hangjához"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Csatlakozva a fájlküldő szerverhez"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Felhasználás fájlátvitelre"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Használat beviteli eszközként"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Hallókészülékkel való használat"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Használat ehhez: LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Párosítás"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PÁROSÍTÁS"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Mégse"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 10f05b0..485af54 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Լսողական ապարատը միացված է"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Միացած է 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 9eacc6c..10f57df 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Alat Bantu Dengar"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Terhubung ke Alat Bantu Dengar"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Terhubung ke LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Terhubung ke media audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Terhubung ke audio ponsel"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Sambungkan ke server transfer file"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Gunakan untuk transfer file"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Gunakan untuk masukan"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gunakan untuk Alat Bantu Dengar"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Digunakan untuk LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Sambungkan"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SAMBUNGKAN"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Batal"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index d67b872..a43eb14 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-hljóð: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-hljóð"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Heyrnartæki"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Tengt við heyrnartæki"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Tengt við LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Tengt við hljóðspilun efnis"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Tengt við hljóð símans"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Tengt við skráaflutningsþjón"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Nota við skráaflutning"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Nota fyrir inntak"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Nota fyrir heyrnartæki"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Nota fyrir LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Para"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PARA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Hætta við"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 27f5c3c..173588b 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Apparecchi acustici"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connessione con gli apparecchi acustici stabilita"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Connesso a LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Collegato ad audio media"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Collegato ad audio telefono"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Collegato al server di trasferimento file"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Usa per trasferimento file"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Utilizza per l\'input"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Utilizza per gli apparecchi acustici"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Usa per LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Accoppia"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ACCOPPIA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annulla"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 371d20a..f969f45 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"מחובר אל מכשירי שמיעה"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"מחובר אל 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 0d85974..620aca6 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"補聴器に接続"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 572d109..daa0fae 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"დაკავშირებულია სმენის მოწყობილობებთან"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"დაკავშირებულია შემდეგთან: 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 8a54e52..28675ac 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -122,7 +122,11 @@
<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>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Есту аппараттарына жалғанған"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<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>
@@ -140,6 +144,8 @@
<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>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<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>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index efc422c..e58ed68 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"បានភ្ជាប់ទៅឧបករណ៍ជំនួយការស្ដាប់"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"បានភ្ជាប់ទៅ 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 91ee100..73f6a21 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ಶ್ರವಣ ಸಾಧನಗಳಿಗೆ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 7d7b9a8..1ff18c6 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"보청기에 연결됨"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 319e61a..58e3107 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Угуу аппараттарына туташып турат"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 5490543..a2b8c6b 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ເຊື່ອມຕໍ່ຫາອຸປະກອນຊ່ວຍຟັງແລ້ວ"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"ເຊື່ອມຕໍ່ຫາ 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index b53e1b0..d8c1a45 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD garsas: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD garsas"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Klausos aparatai"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Prisijungta prie klausos aparatų"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Prisijungta prie LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Prijungta prie medijos garso įrašo"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Prijungta prie telefono garso"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Prijungta prie failų perkėlimo serverio"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Naudoti failų perkėlimui"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Naudoti įvedant"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Naudoti su klausos aparatais"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Naudoti LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Susieti"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SUSIETI"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Atšaukti"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 053e97e..9ac8c65 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Dzirdes aparāti"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO profils"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Izveidots savienojums ar dzirdes aparātiem"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Izveidots savienojums ar LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Savienots ar multivides audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Savienots ar tālruņa audio"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Savienots ar failu pārsūtīšanas serveri"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Izmantot faila pārsūtīšanai"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Izmantot ievadei"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Izmantot dzirdes aparātiem"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Izmantot LE_AUDIO profilam"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Izveidot pāri"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SAVIENOT PĀRĪ"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Atcelt"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 5d348b6..c08fd24 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Поврзано со слушни помагала"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Поврзано на 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index b9e719b3..b2b6a40 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ശ്രവണ സഹായികളിലേക്ക് കണക്റ്റ് ചെയ്തു"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index d905541..b62d103 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_АУДИО"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Сонсголын төхөөрөмжтэй холбосон"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"LE_АУДИОНД холбогдлоо"</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>
@@ -140,6 +142,7 @@
<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_АУДИОНД ашиглах"</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>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 4365b20..a816f49 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"श्रवण यंत्रांशी कनेक्ट केले आहे"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index e054bd0..0841328 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Alat Bantu Dengar"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Disambungkan pada Alat Bantu Dengar"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Disambungkan kepada LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Disambungkan ke audio media"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Disambungkan ke audio telefon"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Bersambung ke pelayan pemindahan fail"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Gunakan untuk pemindahan fail"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Gunakan untuk input"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gunakan untuk Alat Bantu Dengar"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Gunakan untuk LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Gandingkan"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"JADIKAN PASANGAN"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Batal"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index ca7ffc9..d5fbdaf 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"နားကြားကိရိယာနှင့် ချိတ်ဆက်ပြီးပါပြီ"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index d355ae5..e7f70d1 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-lyd"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Høreapparater"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Koblet til høreapparater"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Koblet til LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Koblet til medielyd"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Koblet til telefonlyd"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Koblet til tjener for filoverføring"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Bruk til filoverføring"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Bruk for inndata"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Bruk for høreapparater"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Bruk for LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Koble til"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"KOBLE TIL"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Avbryt"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 508222f..8fc329f8 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"श्रवण यन्त्रहरूमा जडान गरियो"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index daef7e1..35e651b 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hoortoestellen"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Verbonden met hoortoestellen"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Verbonden met LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Verbonden met audio van medium"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Verbonden met audio van telefoon"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Verbonden met server voor bestandsoverdracht"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Gebruiken voor bestandsoverdracht"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Gebruiken voor invoer"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gebruiken voor hoortoestellen"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Gebruiken voor LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Koppelen"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"KOPPELEN"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annuleren"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 6faf614..2200567 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -122,7 +122,11 @@
<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>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ଶ୍ରବଣ ଯନ୍ତ୍ରକୁ ସଂଯୋଗ ହୋଇଛି"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<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>
@@ -140,6 +144,8 @@
<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>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<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>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 475ce35..3c1cfcb 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -122,7 +122,11 @@
<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>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ਸੁਣਨ ਦੇ ਸਾਧਨਾਂ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<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>
@@ -140,6 +144,8 @@
<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>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<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>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 7c656afe..1eb2dd9 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Dźwięk HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Dźwięk HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparaty słuchowe"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Połączono z aparatami słuchowymi"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Połączono z LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Połączono z funkcją audio multimediów"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Połączono z funkcją audio telefonu"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Połączono z serwerem transferu plików"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Użyj do transferu plików"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Użyj do wprowadzania"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Użyj z aparatami słuchowymi"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Używaj dla LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Sparuj"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SPARUJ"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Anuluj"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 2356f41..38d637f 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Áudio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparelhos auditivos"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a aparelhos auditivos"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Conectado a LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado ao áudio da mídia"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Conectado ao áudio do smartphone"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Conectado ao servidor de transferência de arquivo"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Usado para transferência de arquivo"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Usar para entrada"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Usar para aparelhos auditivos"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Usar para LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Parear"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PAREAR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 43155a7..ebe5753 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Áudio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparelhos auditivos"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Ligado a aparelhos auditivos"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Ligado a LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ligado ao áudio de multimédia"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Ligado ao áudio do telefone"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Ligado ao servidor de transferência de ficheiros"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Utilizar para transferência de ficheiros"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Utilizar para entrada"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Utilizar para aparelhos auditivos"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Utilizar para LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Sincr."</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SINCRONIZAR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 2356f41..38d637f 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Áudio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparelhos auditivos"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a aparelhos auditivos"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Conectado a LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado ao áudio da mídia"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Conectado ao áudio do smartphone"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Conectado ao servidor de transferência de arquivo"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Usado para transferência de arquivo"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Usar para entrada"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Usar para aparelhos auditivos"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Usar para LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Parear"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PAREAR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 083c2b9..ce58f1c 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparate auditive"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectat la aparatul auditiv"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Conectat la LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectat la profilul pentru conținut media audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Conectat la componenta audio a telefonului"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Conectat la serverul de transfer de fișiere"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Utilizați pentru transferul de fișiere"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Utilizați pentru introducere date"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Folosiți pentru aparatele auditive"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Folosiți pentru LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Asociați"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"CONECTAȚI"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Anulați"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 0a0fce34..c158a14 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD Audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD Audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слуховые аппараты"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Слуховой аппарат подключен"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Подключено к 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 5b30c81..41f10c9 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ශ්රවණාධාරක වෙත සම්බන්ධ කළා"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 0d929db..801c213 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -122,7 +122,9 @@
<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">"Načúvadlá"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Pripojené k načúvadlám"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Pripojené k profilu LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Pripojené ku zvukovému médiu"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Pripojené ku zvuku telefónu"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Pripojené na server pre prenos údajov"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Použiť na prenos súborov"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Použiť pre vstup"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Použiť pre načúvadlá"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Používať s profilom LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Párovať"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PÁROVAŤ"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Zrušiť"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 7a559fc..a331018 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Zvok visoke kakovosti: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Zvok visoke kakovosti"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni pripomočki"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Povezava s slušnimi pripomočki je vzpostavljena"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Povezano s profilom LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezan s profilom za predstavnostni zvok"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Povezava s profilom za zvok telefona vzpostavljena"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Povezava s strežnikom za prenos datotek je vzpostavljena"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Uporabi za prenos datotek"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Uporabi za vnos"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Uporabi za slušne pripomočke"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Uporaba za profil LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Seznani"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SEZNANI"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Prekliči"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 4a1eeff..cb9bea8 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparatet e dëgjimit"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Lidhur me aparatet e dëgjimit"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Lidhur me LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"U lidh me audion e medias"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"U lidh me audion e telefonit"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"U lidh me serverin e transferimit të skedarëve"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Përdor për transferimin e skedarëve"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Përdore për hyrjen"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Përdore për aparatet e dëgjimit"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Përdor për LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Çifto"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ÇIFTO"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Anulo"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 0359833..9e90333 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Повезано са слушним апаратима"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Повезано са 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index a0b92a2..215d9ad 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-ljud: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-ljud"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hörapparater"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Ansluten till hörapparater"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Ansluten till LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ansluten till medialjud"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Ansluten till telefonens ljud"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Ansluten till filöverföringsserver"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Använd för filöverföring"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Använd för inmatning"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Använd med hörapparater"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Använd för LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Parkoppla"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PARKOPPLA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Avbryt"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 76136c8..f51825b 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Sauti ya HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Sauti ya HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Vifaa vya Kusaidia Kusikia"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Imeunganishwa kwenye Vifaa vya Kusaidia Kusikia"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Imeunganishwa kwenye LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Imeunganishwa kwenye sikika ya njia ya mawasiliano"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Imeunganishwa kwenye sauti ya simu"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Imeunganishwa kwenye seva ya kuhamisha faili"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Tumia kwa hali faili"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Tumia kwa kuingiza"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Tumia kwenye Vifaa vya Kusaidia Kusikia"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Tumia kwa ajili ya LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Oanisha"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"OANISHA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Ghairi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 185104f..8128683 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"செவித்துணை கருவிகளுடன் இணைக்கப்பட்டது"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index d3c13a9..298f850 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"వినికిడి మద్దతు ఉపకరణాలకు కనెక్ట్ చేయబడింది"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 51a0420..e18c649 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"เชื่อมต่อกับเครื่องช่วยฟังแล้ว"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"เชื่อมต่อกับ 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 1bc84af..628bacc 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Mga Hearing Aid"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Nakakonekta sa Mga Hearing Aid"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Nakakonekta sa LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Konektado sa media audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Nakakonekta sa audio ng telepono"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Nakakonekta sa server sa paglilipat ng file"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Ginagamit para sa paglilipat ng file"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Gamitin para sa input"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gamitin para sa Mga Hearing Aid"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Gamitin para sa LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Ipares"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"IPARES"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Kanselahin"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index a00457a..3e30d43 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ses: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ses"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"İşitme Cihazları"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"İşitme Cihazlarına Bağlandı"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"LE_AUDIO\'ya bağlandı"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Medya sesine bağlanıldı"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Telefon sesine bağlandı"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Dosya aktarım sunucusuna bağlandı"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Dosya aktarımı için kullan"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Giriş için kullan"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"İşitme Cihazları için kullan"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"LE_AUDIO kullan"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Eşle"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"EŞLE"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"İptal"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 6aac2932..8683953 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Підключено до слухових апаратів"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Підключено до 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 14cea9a..09e50f6 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"سماعتی آلات سے منسلک ہے"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 47c828d..d0b9506 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Eshitish apparatlari"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Eshitish apparatlariga ulangan"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Ulandi: LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Audio qurilmasiga ulangan"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Telefon karnayiga ulanildi"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Fayl almashinish serveriga ulanildi"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Fayl almashinish uchun foydalanish"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Kiritish qurilmasi sifatida foydalanish"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Eshitish apparatlari uchun foydalanish"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"LE_AUDIO uchun foydalanish"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"OK"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ULANISH"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Bekor qilish"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index aaaaada..9eebd02 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Âm thanh HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Âm thanh HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Thiết bị trợ thính"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Đã kết nối với Thiết bị trợ thính"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Đã kết nối với LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Đã kết nối với âm thanh nội dung nghe nhìn"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Đã kết nối với âm thanh điện thoại"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Đã kết nối với máy chủ chuyển tệp"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Sử dụng để chuyển tệp"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Sử dụng để nhập"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Dùng cho Thiết bị trợ thính"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Dùng cho LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Ghép nối"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"GHÉP NỐI"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Hủy"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index c85dba0..3ed1860 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -122,7 +122,9 @@
<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="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"已连接到助听器"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"已连接到 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index dccd1df..965e78f 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"高清音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"高清音訊"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"助聽器"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"已連接助聽器"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"已連接 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>
@@ -140,6 +142,7 @@
<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>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index afa27aa..5b74ab0 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -122,7 +122,11 @@
<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>
+ <!-- no translation found for bluetooth_profile_le_audio (5158149987518342036) -->
+ <skip />
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"已連接到助聽器"</string>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_connected (3162538609379333442) -->
+ <skip />
<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>
@@ -140,6 +144,8 @@
<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>
+ <!-- no translation found for bluetooth_le_audio_profile_summary_use_for (2778318636027348572) -->
+ <skip />
<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>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 9b3063d..1af1fa1 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -122,7 +122,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Umsindo we-HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Umsindo we-HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Izinsiza zokuzwa"</string>
+ <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"I-LE_AUDIO"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Kuxhumeke kwizinsiza zokuzwa"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"Kuxhunywe ku-LE_AUDIO"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ixhume emsindweni wemidiya"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Ixhunywe kumsindo wefoni"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Ixhunywe kwiseva yokudlulisa ifayela"</string>
@@ -140,6 +142,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Sebenziselwa ukudlulisa ifayela"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Isetshenziselwa okufakwayo"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Sebenzisa izinsiza zokuzwa"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Sebenzisela i-LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Bhangqa"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"BHANGQA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Khansela"</string>
diff --git a/packages/SystemUI/res-product/values-te/strings.xml b/packages/SystemUI/res-product/values-te/strings.xml
index 1773f90..511e095 100644
--- a/packages/SystemUI/res-product/values-te/strings.xml
+++ b/packages/SystemUI/res-product/values-te/strings.xml
@@ -38,8 +38,8 @@
<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="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>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 427af68..f310a7f 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-fi sal vir nou nie outomaties koppel nie"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Sien alles"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Ontkoppel Ethernet om netwerke te wissel"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Om toestelervaring te verbeter, kan programme en dienste steeds enige tyd na wi‑fi-netwerke soek, selfs wanneer wi‑fi af is. Jy kan dit in Wi-fi-opsporing-instellings verander. "<annotation id="link">"Verander"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wil die volgende teël by Kitsinstellings voeg"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Voeg teël by"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Moenie teël byvoeg nie"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index a158d7f..ffdfba6 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -1179,6 +1179,7 @@
<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">"የመሣሪያ ተሞክሮን ለማሻሻል፣ መተግበሪያዎች እና አገልግሎቶች አሁንም በማንኛውም ጊዜ የWi-Fi አውታረ መረቦችን መቃኘት ይችላሉ፣ Wi-Fi ጠፍቶ ቢሆንም እንኳ። ይህንን በ Wi‑Fi ቅኝት ቅንብሮች ውስጥ መቀየር ይችላሉ። "<annotation id="link">"ቀይር"</annotation></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>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index ae4125b..48e101b 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -1203,6 +1203,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"لن يتم الاتصال بشبكة Wi-Fi تلقائيًا في الوقت الحالي."</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">"لتحسين تجربتك على الجهاز، يظل بإمكان التطبيقات والخدمات البحث عن شبكات Wi‑Fi في أي وقت، حتى عند إيقاف شبكة Wi‑Fi. وبإمكانك تغيير هذا الخيار في إعدادات البحث عن شبكات Wi-Fi. "<annotation id="link">"تغيير"</annotation></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>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 9da6246..f9cb599 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -24,19 +24,19 @@
<string name="status_bar_no_notifications_title" msgid="7812479124981107507">"কোনো জাননী নাই"</string>
<string name="status_bar_ongoing_events_title" msgid="3986169317496615446">"চলিত"</string>
<string name="status_bar_latest_events_title" msgid="202755896454005436">"জাননীসমূহ"</string>
- <string name="battery_low_title" msgid="6891106956328275225">"বেটাৰি অতি সোনকালে শেষ হ\'ব পাৰে"</string>
+ <string name="battery_low_title" msgid="6891106956328275225">"বেটাৰী অতি সোনকালে শেষ হ\'ব পাৰে"</string>
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> বাকী আছে"</string>
<string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> অৱশিষ্ট আছে, আপোনাৰ ব্যৱহাৰক ভিত্তি কৰি প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
<string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> অৱশিষ্ট আছে, প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী"</string>
- <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"<xliff:g id="PERCENTAGE">%s</xliff:g> বাকী আছে। বেটাৰি সঞ্চয়কাৰী অন হৈ আছে।"</string>
+ <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"<xliff:g id="PERCENTAGE">%s</xliff:g> বাকী আছে। বেটাৰী সঞ্চয়কাৰী অন হৈ আছে।"</string>
<string name="invalid_charger" msgid="4370074072117767416">"ইউএছবি জৰিয়তে চ্চাৰ্জ কৰিব নোৱাৰি। আপোনাৰ ডিভাইচৰ লগত পোৱা চ্চাৰ্জাৰটো ব্যৱহাৰ কৰক।"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"ইউএছবি জৰিয়তে চ্চাৰ্জ কৰিব নোৱাৰি"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"আপোনাৰ ডিভাইচৰ লগত পোৱা চ্চাৰ্জাৰটো ব্যৱহাৰ কৰক।"</string>
<string name="battery_low_why" msgid="2056750982959359863">"ছেটিং"</string>
- <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"বেটাৰি সঞ্চয়কাৰী অন কৰেনে?"</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="4553256017945469937">"বেটাৰি সঞ্চয়কাৰী অন কৰক"</string>
+ <string name="battery_saver_start_action" msgid="4553256017945469937">"বেটাৰী সঞ্চয়কাৰী অন কৰক"</string>
<string name="status_bar_settings_settings_button" msgid="534331565185171556">"ছেটিং"</string>
<string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"ৱাই-ফাই"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string>
@@ -193,11 +193,11 @@
<string name="accessibility_compatibility_zoom_example" msgid="2617218726091234073">"স্ক্ৰীনৰ আকাৰ ডাঙৰ কৰিবলৈ জুম কৰক।"</string>
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ব্লুটুথ সংযোগ হ’ল।"</string>
<string name="accessibility_bluetooth_disconnected" msgid="7195823280221275929">"ব্লুটুথ সংযোগ বিচ্ছিন্ন কৰা হ’ল।"</string>
- <string name="accessibility_no_battery" msgid="3789287732041910804">"বেটাৰি শেষ"</string>
- <string name="accessibility_battery_one_bar" msgid="8868347318237585329">"বেটাৰিৰ এডাল দণ্ড।"</string>
- <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"বেটাৰিৰ দুডাল দণ্ড।"</string>
- <string name="accessibility_battery_three_bars" msgid="118341923832368291">"বেটাৰিৰ তিনিডাল দণ্ড।"</string>
- <string name="accessibility_battery_full" msgid="1480463938961288494">"বেটাৰি পূৰাকৈ চ্চাৰ্জ হৈছে।"</string>
+ <string name="accessibility_no_battery" msgid="3789287732041910804">"বেটাৰী শেষ"</string>
+ <string name="accessibility_battery_one_bar" msgid="8868347318237585329">"বেটাৰীৰ এডাল দণ্ড।"</string>
+ <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"বেটাৰীৰ দুডাল দণ্ড।"</string>
+ <string name="accessibility_battery_three_bars" msgid="118341923832368291">"বেটাৰীৰ তিনিডাল দণ্ড।"</string>
+ <string name="accessibility_battery_full" msgid="1480463938961288494">"বেটাৰী পূৰাকৈ চাৰ্জ হৈছে।"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"বেটাৰীৰ চাৰ্জৰ শতাংশ অজ্ঞাত।"</string>
<string name="accessibility_wifi_name" msgid="4863440268606851734">"<xliff:g id="WIFI">%s</xliff:g>ৰ লগত সংযোগ কৰা হ’ল।"</string>
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>ৰ লগত সংযোগ কৰা হ’ল।"</string>
@@ -229,10 +229,10 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"এয়াৰপ্লে’ন ম’ড।"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"ভিপিএন অন অৱস্থাত আছে।"</string>
<string name="accessibility_no_sims" msgid="5711270400476534667">"কোনো ছিম কাৰ্ড নাই"</string>
- <string name="accessibility_battery_details" msgid="6184390274150865789">"বেটাৰিৰ বিৱৰণসমূহ খোলক"</string>
- <string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> শতাংশ বেটাৰি।"</string>
+ <string name="accessibility_battery_details" msgid="6184390274150865789">"বেটাৰীৰ বিৱৰণসমূহ খোলক"</string>
+ <string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> শতাংশ বেটাৰী।"</string>
<string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি বেটাৰী <xliff:g id="PERCENTAGE">%1$s</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" msgid="8892191177774027364">"বেটাৰী চাৰ্জ হৈ আছে, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> শতাংশ।"</string>
<string name="accessibility_settings_button" msgid="2197034218538913880">"ছিষ্টেমৰ ছেটিং৷"</string>
<string name="accessibility_notifications_button" msgid="3960913924189228831">"জাননীসমূহ।"</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"সকলো জাননীবোৰ চাওক"</string>
@@ -258,7 +258,7 @@
<string name="accessibility_quick_settings_wifi_changed_off" msgid="2230487165558877262">"ৱাই-ফাই অফ কৰা হ’ল।"</string>
<string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"ৱাই-ফাই অন কৰা হ’ল।"</string>
<string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"ম’বাইল <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
- <string name="accessibility_quick_settings_battery" msgid="533594896310663853">"বেটাৰি <xliff:g id="STATE">%s</xliff:g>।"</string>
+ <string name="accessibility_quick_settings_battery" msgid="533594896310663853">"বেটাৰী <xliff:g id="STATE">%s</xliff:g>।"</string>
<string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"এয়াৰপ্লেইন ম\'ড অফ হৈ আছে৷"</string>
<string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"এয়াৰপ্লেইন ম\'ড অন হৈ আছে৷"</string>
<string name="accessibility_quick_settings_airplane_changed_off" msgid="8880183481476943754">"এয়াৰপ্লেইন ম\'ড অফ কৰা হ’ল।"</string>
@@ -338,7 +338,7 @@
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="6595808498429809855">"ব্লুটুথ (<xliff:g id="NUMBER">%d</xliff:g>টা ডিভাইচ)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="6375098046500790870">"ব্লুটুথ বন্ধ অৱস্থাত আছে"</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_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>
@@ -391,7 +391,7 @@
<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_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_tethering_label" msgid="5257299852322475780">"টেডাৰ কৰি থকা হৈছে"</string>
<string name="quick_settings_hotspot_label" msgid="1199196300038363424">"হটস্পট"</string>
@@ -504,9 +504,9 @@
<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="battery_saver_notification_title" msgid="8419266546034372562">"বেটাৰি সঞ্চয়কাৰী অন হৈ আছে"</string>
+ <string name="battery_saver_notification_title" msgid="8419266546034372562">"বেটাৰী সঞ্চয়কাৰী অন হৈ আছে"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"কাৰ্যদক্ষতা আৰু নেপথ্য ডেটা হ্ৰাস কৰে"</string>
- <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"বেটাৰি সঞ্চয়কাৰী অফ কৰক"</string>
+ <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"বেটাৰী সঞ্চয়কাৰী অফ কৰক"</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>
@@ -657,8 +657,8 @@
<string name="output_service_wifi" msgid="9003667810868222134">"ৱাই-ফাই"</string>
<string name="output_service_bt_wifi" msgid="7186882540475524124">"ব্লুটুথ আৰু ৱাই-ফাই"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string>
- <string name="show_battery_percentage" msgid="6235377891802910455">"সংযুক্ত বেটাৰিৰ কিমান শতাংশ বাকী আছে দেখুওৱাক"</string>
- <string name="show_battery_percentage_summary" msgid="9053024758304102915">"চাৰ্জ হৈ নথকা অৱস্থাত বেটাৰি কিমান শতাংশ বাকী স্থিতি দণ্ডৰ ভিতৰত দেখুৱাওক"</string>
+ <string name="show_battery_percentage" msgid="6235377891802910455">"সংযুক্ত বেটাৰীৰ কিমান শতাংশ বাকী আছে দেখুওৱাক"</string>
+ <string name="show_battery_percentage_summary" msgid="9053024758304102915">"চাৰ্জ হৈ নথকা অৱস্থাত বেটাৰী কিমান শতাংশ বাকী স্থিতি দণ্ডৰ ভিতৰত দেখুৱাওক"</string>
<string name="quick_settings" msgid="6211774484997470203">"ক্ষিপ্ৰ ছেটিং"</string>
<string name="status_bar" msgid="4357390266055077437">"স্থিতি দণ্ড"</string>
<string name="overview" msgid="3522318590458536816">"অৱলোকন"</string>
@@ -696,7 +696,7 @@
<string name="remove_from_settings_prompt" msgid="551565437265615426">"ছেটিঙৰ পৰা System UI Tuner আঁতৰাই ইয়াৰ সুবিধাসমূহ ব্যৱহাৰ কৰাটো বন্ধ কৰিবনে?"</string>
<string name="activity_not_found" msgid="8711661533828200293">"আপোনাৰ ডিভাইচত এপ্লিকেশ্বনটো ইনষ্টল কৰা হোৱা নাই"</string>
<string name="clock_seconds" msgid="8709189470828542071">"ঘড়ীৰ ছেকেণ্ড দেখুৱাওক"</string>
- <string name="clock_seconds_desc" msgid="2415312788902144817">"স্থিতি দণ্ডত ঘড়ীৰ ছেকেণ্ড দেখুৱাওক। এই কার্যই বেটাৰিৰ অৱস্থাত প্ৰভাৱ পেলাব পাৰে।"</string>
+ <string name="clock_seconds_desc" msgid="2415312788902144817">"স্থিতি দণ্ডত ঘড়ীৰ ছেকেণ্ড দেখুৱাওক। এই কার্যই বেটাৰীৰ জীৱনকালত প্ৰভাৱ পেলাব পাৰে।"</string>
<string name="qs_rearrange" msgid="484816665478662911">"ক্ষিপ্ৰ ছেটিং পুনৰ সজাওক"</string>
<string name="show_brightness" msgid="6700267491672470007">"দ্ৰুত ছেটিঙত উজ্জ্বলতা দেখুৱাওক"</string>
<string name="experimental" msgid="3549865454812314826">"পৰীক্ষামূলক"</string>
@@ -802,8 +802,8 @@
<item quantity="one"> %d মিনিট</item>
<item quantity="other"> %d মিনিট</item>
</plurals>
- <string name="battery_panel_title" msgid="5931157246673665963">"বেটাৰিৰ ব্যৱহাৰ"</string>
- <string name="battery_detail_charging_summary" msgid="8821202155297559706">"চ্চাৰ্জ কৰি থকাৰ সময়ত বেটাৰি সঞ্চয়কাৰী উপলব্ধ নহয়।"</string>
+ <string name="battery_panel_title" msgid="5931157246673665963">"বেটাৰীৰ ব্যৱহাৰ"</string>
+ <string name="battery_detail_charging_summary" msgid="8821202155297559706">"চাৰ্জ কৰি থকাৰ সময়ত বেটাৰী সঞ্চয়কাৰী উপলব্ধ নহয়।"</string>
<string name="battery_detail_switch_title" msgid="6940976502957380405">"বেটাৰী সঞ্চয়কাৰী"</string>
<string name="battery_detail_switch_summary" msgid="3668748557848025990">"কাৰ্যদক্ষতা আৰু নেপথ্য ডেটা হ্ৰাস কৰে"</string>
<string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> বুটাম"</string>
@@ -853,7 +853,7 @@
<string name="volume_and_do_not_disturb" msgid="502044092739382832">"অসুবিধা নিদিব"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ভলিউম বুটামসমূহৰ শ্বৰ্টকাট"</string>
<string name="volume_up_silent" msgid="1035180298885717790">"ভলিউম বঢ়োৱা বুটাম ব্যৱহাৰ কৰি অসুবিধা নিদিব নিষ্ক্ৰিয় কৰক"</string>
- <string name="battery" msgid="769686279459897127">"বেটাৰি"</string>
+ <string name="battery" msgid="769686279459897127">"বেটাৰী"</string>
<string name="clock" msgid="8978017607326790204">"ঘড়ী"</string>
<string name="headset" msgid="4485892374984466437">"হেডছেট"</string>
<string name="accessibility_long_click_tile" msgid="210472753156768705">"ছেটিং খোলক"</string>
@@ -962,7 +962,7 @@
<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_battery" msgid="9219995638046695106">"বেটাৰী"</string>
<string name="notification_channel_screenshot" msgid="7665814998932211997">"স্ক্ৰীণশ্বটসমূহ"</string>
<string name="notification_channel_general" msgid="4384774889645929705">"সাধাৰণ বার্তাসমূহ"</string>
<string name="notification_channel_storage" msgid="2720725707628094977">"ষ্ট\'ৰেজ"</string>
@@ -986,7 +986,7 @@
<string name="qs_dnd_keep" msgid="3829697305432866434">"Keep"</string>
<string name="qs_dnd_replace" msgid="7712119051407052689">"সলনি কৰক"</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"নেপথ্যত চলি থকা এপসমূহ"</string>
- <string name="running_foreground_services_msg" msgid="3009459259222695385">"বেটাৰি আৰু ডেটাৰ ব্যৱহাৰৰ বিষয়ে বিশদভাৱে জানিবলৈ টিপক"</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>ৰ জৰিয়তে ডেটা সংযোগ বা ইণ্টাৰনেট সংযোগ নাপাব। কেৱল ৱাই-ফাইৰ যোগেৰে ইণ্টাৰনেট উপলব্ধ হ\'ব।"</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"আপোনাৰ বাহক"</string>
@@ -997,11 +997,11 @@
<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="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="auto_saver_enabled_title" msgid="4294726198280286333">"বেটাৰি সঞ্চয়কাৰীৰ সময়সূচী অন কৰা অৱস্থাত আছে"</string>
- <string name="auto_saver_enabled_text" msgid="7889491183116752719">"বেটাৰি চ্চাৰ্জৰ স্তৰ <xliff:g id="PERCENTAGE">%d</xliff:g>%%তকৈ কম হোৱাৰ লগে লগে বেটাৰি সঞ্চয়কাৰী স্বয়ংক্ৰিয়ভাৱে অন হ’ব।"</string>
+ <string name="auto_saver_enabled_title" msgid="4294726198280286333">"বেটাৰী সঞ্চয়কাৰীৰ সময়সূচী অন কৰা অৱস্থাত আছে"</string>
+ <string name="auto_saver_enabled_text" msgid="7889491183116752719">"বেটাৰী চাৰ্জৰ স্তৰ <xliff:g id="PERCENTAGE">%d</xliff:g>%%তকৈ কম হোৱাৰ লগে লগে বেটাৰী সঞ্চয়কাৰী স্বয়ংক্ৰিয়ভাৱে অন হ’ব।"</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"ছেটিং"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"বুজি পালোঁ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI হীপ ডাম্প কৰক"</string>
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"এতিয়া ৱাই-ফাই স্বয়ংক্ৰিয়ভাৱে সংযুক্ত নহ’ব"</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">"ডিভাইচ ব্যৱহাৰৰ অভিজ্ঞতা উন্নত কৰিবলৈ ৱাই-ফাই অফ থকা অৱস্থাতো এপ্ আৰু সেৱাসমূহে ৱাই-ফাই নেটৱৰ্কবোৰ স্কেন কৰিব পাৰে। আপুনি ৱাই-ফাই স্কেনিঙৰ ছেটিঙত এইটো সলনি কৰিব পাৰে। "<annotation id="link">"সলনি কৰক"</annotation></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>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 9b4b42b..72b9836 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi hələlik avtomatik qoşulmayacaq"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Hamısına baxın"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Şəbəkəni dəyişmək üçün etherneti ayırın"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Cihaz təcrübəsini yaxşılaşdırmaq üçün Wi-Fi deaktiv olduqda belə, tətbiqlər və xidmətlər Wi-Fi şəbəkəsini axtara biləcək. Bunu Wi-Fi axtarışı ayarlarında dəyişə bilərsiniz. "<annotation id="link">"Dəyişin"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> aşağıdakı mozaiki Sürətli Ayarlara əlavə etmək istəyir"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Mozaik əlavə edin"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Mozaik əlavə etməyin"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 4317599..f9468ee 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -1185,6 +1185,7 @@
<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="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>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 535144f..bee7943 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -1191,6 +1191,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Аўтаматычнае падключэнне да Wi-Fi адсутнічае"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Паказаць усе"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Каб падключыцца да сетак, выключыце Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Каб палепшыць працу прылады, вы можаце дазволіць праграмам і сэрвісам шукаць сеткі Wi-Fi, нават калі Wi‑Fi выключаны. Змяніць гэты рэжым можна ў наладах пошуку сетак Wi-Fi. "<annotation id="link">"Змяніць"</annotation></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>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 2f54457..e126034 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Засега Wi-Fi няма да се свързва автоматично"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Вижте всички"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"За да превключите мрежите, прекъснете връзката с Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"С цел подобряване на практическата работа с устройството приложенията и услугите пак могат да сканират за Wi‑Fi мрежи по всяко време дори когато функцията за Wi‑Fi e изключена. Можете да промените съответното поведение от настройките за сканиране за Wi‑Fi. "<annotation id="link">"Промяна"</annotation></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>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 2dc23f0..bde0d8c 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -1090,8 +1090,7 @@
<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="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চলছে"</string>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>টির মধ্যে <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>টি"</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="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চালান"</string>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"এখন ওয়াই-ফাই নিজে থেকে কানেক্ট হবে না"</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">"ডিভাইস সংক্রান্ত অভিজ্ঞতা আরও ভাল করতে, অ্যাপ ও পরিষেবা যেকোনও সময় আপনার ওয়াই-ফাই নেটওয়ার্ক স্ক্যান করতে পারবে, এমনকি ডিভাইসের ওয়াই-ফাই বন্ধ করা থাকলেও। ওয়াই-ফাই স্ক্যানিং সেটিংস থেকে আপনি এটি পরিবর্তন করতে পারবেন। "<annotation id="link">"পরিবর্তন করুন"</annotation></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>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 0fc1405..c29cc31 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -1185,6 +1185,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"WiFi se trenutno ne može automatski povezati"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Prikaži sve"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Da promijenite mrežu, isključite ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Radi poboljšanja iskustva s uređajem aplikacije i usluge i dalje mogu bilo kada skenirati WiFi mreže, čak i kada je WiFi isključen. Ovo možete promijeniti u Postavkama skeniranja WiFi mreže. "<annotation id="link">"Promijeni"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> želi dodati sljedeću karticu u Brze postavke"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj karticu"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nemoj dodati karticu"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 9d8f599..751a49d 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Per ara la Wi‑Fi no es connectarà automàticament"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Mostra-ho tot"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Per canviar de xarxa, desconnecta la connexió Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Per millorar l\'experiència del dispositiu, les aplicacions i els serveis poden cercar xarxes Wi‑Fi en qualsevol moment, fins i tot quan la Wi‑Fi estigui desactivada. Pots canviar aquesta opció a la configuració de cerca de xarxes Wi‑Fi. "<annotation id="link">"Canvia-la"</annotation>"."</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vol afegir la icona següent a la configuració ràpida"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Afegeix la icona"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"No afegeixis la icona"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 1393431..1aa9c44 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -1191,6 +1191,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi se prozatím nebude připojovat automaticky"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Zobrazit vše"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Pokud chcete přepnout sítě, odpojte ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Za účelem lepšího fungování zařízení mohou aplikace a služby vyhledávat sítě Wi-Fi, i když je připojení Wi-Fi vypnuté. Toto chování můžete změnit v nastavení vyhledávání Wi-Fi. "<annotation id="link">"Změnit"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"Aplikace <xliff:g id="APPNAME">%1$s</xliff:g> chce do Rychlého nastavení přidat následující dlaždici"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Přidat dlaždici"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepřidávat dlaždici"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 1502dea..492546f 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Ingen automatisk forbindelse til Wi-Fi i øjeblikket"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Se alle"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Afbryd ethernetforbindelsen for at skifte netværk"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"For at forbedre brugeroplevelsen på enheden kan apps og tjenester stadig til enhver tid scanne efter Wi‑Fi-netværk, også selvom Wi‑Fi er deaktiveret. Du kan ændre dette i indstillingerne for Wi-Fi-scanning. "<annotation id="link">"Skift indstilling"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vil gerne føje dette handlingsfelt til Kvikmenu"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tilføj handlingsfelt"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Tilføj ikke felt"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index d4ebeda..085e082 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -1090,8 +1090,7 @@
<string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Einstellungen"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wird gerade über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergegeben"</string>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> von <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Wiedergeben"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> öffnen"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergeben"</string>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Zurzeit wird keine automatische WLAN-Verbindung hergestellt"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Alle ansehen"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Trenne das Ethernetkabel, um das Netzwerk zu wechseln"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Zur Verbesserung der Gerätenutzung können Apps und Dienste weiter nach WLANs suchen, auch wenn die WLAN-Funktion deaktiviert ist. Dies lässt sich in den Einstellungen für die WLAN-Suche ändern. "<annotation id="link">"Ändern"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> möchte die folgende Kachel den Schnelleinstellungen hinzufügen"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Kachel hinzufügen"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Kachel nicht hinzu"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 576a806..b6ef245 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Δεν θα γίνεται προς το παρόν αυτόματη σύνδεση Wi-Fi."</string>
<string name="see_all_networks" msgid="3773666844913168122">"Εμφάνιση όλων"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Για εναλλαγή δικτύων, αποσυνδέστε το ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Για βελτίωση της εμπειρίας στη συσκευή, οι εφαρμογές και οι υπηρεσίες μπορούν ακόμα να εκτελούν σάρωση για δίκτυα Wi‑Fi ανά πάσα στιγμή, ακόμα και όταν το Wi‑Fi είναι απενεργοποιημένο. Μπορείτε να αλλάξετε αυτήν τη ρύθμιση στις ρυθμίσεις της Σάρωσης Wi‑Fi. "<annotation id="link">"Αλλαγή"</annotation></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>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 3898159..d50402f 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi‑Fi won’t auto-connect for now"</string>
<string name="see_all_networks" msgid="3773666844913168122">"See all"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"To switch networks, disconnect Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"To improve device experience, apps and services can still scan for Wi‑Fi networks at any time, even when Wi‑Fi is off. You can change this in Wi‑Fi scanning settings. "<annotation id="link">"Change"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wants to add the following tile to Quick Settings"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 5a31735..d30be77 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi‑Fi won’t auto-connect for now"</string>
<string name="see_all_networks" msgid="3773666844913168122">"See all"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"To switch networks, disconnect Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"To improve device experience, apps and services can still scan for Wi‑Fi networks at any time, even when Wi‑Fi is off. You can change this in Wi‑Fi scanning settings. "<annotation id="link">"Change"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wants to add the following tile to Quick Settings"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 3898159..d50402f 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi‑Fi won’t auto-connect for now"</string>
<string name="see_all_networks" msgid="3773666844913168122">"See all"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"To switch networks, disconnect Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"To improve device experience, apps and services can still scan for Wi‑Fi networks at any time, even when Wi‑Fi is off. You can change this in Wi‑Fi scanning settings. "<annotation id="link">"Change"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wants to add the following tile to Quick Settings"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 3898159..d50402f 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi‑Fi won’t auto-connect for now"</string>
<string name="see_all_networks" msgid="3773666844913168122">"See all"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"To switch networks, disconnect Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"To improve device experience, apps and services can still scan for Wi‑Fi networks at any time, even when Wi‑Fi is off. You can change this in Wi‑Fi scanning settings. "<annotation id="link">"Change"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wants to add the following tile to Quick Settings"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 1ec39d4..880be2b 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi‑Fi won’t auto-connect for now"</string>
<string name="see_all_networks" msgid="3773666844913168122">"See all"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"To switch networks, disconnect ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"To improve device experience, apps and services can still scan for Wi‑Fi networks at any time, even when Wi‑Fi is off. You can change this in Wi‑Fi scanning settings. "<annotation id="link">"Change"</annotation>""</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wants to add the following tile to Quick Settings"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index e8f8b36cf..f68196bf 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Por ahora, el Wi-Fi no se conectará automáticamente"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Ver todo"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para cambiar de red, desconéctate de Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para mejorar la experiencia con el dispositivo, las apps y los servicios pueden seguir buscando redes Wi-Fi en cualquier momento, incluso cuando la conexión Wi-Fi esté desactivada. Puedes cambiar este parámetro en la configuración de búsqueda de Wi-Fi. "<annotation id="link">"Cambiar"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> quiere agregar el siguiente azulejo a la Configuración rápida"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Agregar azulejo"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"No agregar azulejo"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 433536a..7f4c0bc 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Por ahora no se conectará automáticamente a redes Wi-Fi"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Ver todo"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para cambiar de red, desconecta el cable Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para mejorar la experiencia con el dispositivo, las aplicaciones y los servicios podrán buscar redes Wi-Fi en cualquier momento, aunque la conexión Wi-Fi esté desactivada. Puedes cambiarlo en los ajustes de búsqueda de redes Wi-Fi. "<annotation id="link">"Cambiar"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> quiere añadir el siguiente recuadro a ajustes rápidos"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Añadir recuadro"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"No añadir recuadro"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index e23f50d..9bd6e83 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"WiFi-ühendust ei looda praegu automaatselt"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Kuva kõik"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Võrkude vahetamiseks katkestage Etherneti-ühendus"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Seadme kasutuskogemuse parandamiseks võivad rakendused ja teenused siiski alati otsida WiFi-võrke isegi siis, kui WiFi on väljas. Seda saab muuta WiFi-skannimise seadetes. "<annotation id="link">"Muuda"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> soovib kiirseadetesse lisada järgmise paani"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Lisa paan"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ära lisa paani"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index de23069..53415d5 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Oraingoz ez da automatikoki konektatuko wifira"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Ikusi guztiak"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Sarea aldatzeko, deskonektatu Ethernet-a"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Gailuaren funtzionamendua hobetzeko, aplikazioek eta zerbitzuek wifi-sareak bilatzen jarraituko dute, baita wifi-konexioa desaktibatuta dagoenean ere. Aukera hori aldatzeko, joan wifi-sareen bilaketaren ezarpenetara. "<annotation id="link">"Aldatu"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak lauza hau gehitu nahi du Ezarpen bizkorrak menuan:"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Gehitu lauza"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ez gehitu lauza"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index dd778af..acb57f8 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -1090,8 +1090,7 @@
<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>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <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_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>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"فعلاً Wi-Fi بهطور خودکار متصل نمیشود"</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">"برای بهبود تجربه استفاده از دستگاه، برنامهها و سرویسها همچنان میتوانند در هر زمانی شبکههای Wi-Fi را اسکن کنند؛ حتی وقتی که Wi-Fi خاموش باشد. میتوانید این مورد را در تنظیمات اسکن کردن Wi‑Fi تغییر دهید. "<annotation id="link">"تغییر"</annotation></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>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 2ea8dd7..0c1db38 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -1090,8 +1090,7 @@
<string name="controls_media_resume" msgid="1933520684481586053">"Jatka"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Asetukset"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> soittaa nyt tätä: <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <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_smartspace_rec_title" msgid="1699818353932537407">"Toista"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Avaa <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Soita <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) sovelluksessa <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi ei toistaiseksi yhdistä automaattisesti"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Näytä kaikki"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Irrota Ethernet-johto, jos haluat vaihtaa verkkoa"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Laitteen käyttökokemuksen parantamiseksi sovellukset ja palvelut voivat hakea Wi-Fi-verkkoja myös silloin, kun Wi-Fi on pois päältä. Voit muuttaa asetusta Wi-Fi-haun asetuksissa. "<annotation id="link">"Muuta"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> haluaa lisätä seuraavan laatan pika-asetuksiin"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Lisää laatta"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Älä lisää laattaa"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index db02e05c..6ece89f 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Connexion automatique au Wi-Fi impossible pour le moment"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Tout afficher"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Pour changer de réseau, débranchez le câble Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Pour améliorer l\'expérience de l\'appareil, les applications et les services peuvent quand même rechercher des réseaux Wi-Fi en tout temps, même lorsque le Wi-Fi est désactivé. Vous pouvez modifier vos préférences dans les paramètres de recherche de réseaux Wi-Fi. "<annotation id="link">"Modifier"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"L\'application <xliff:g id="APPNAME">%1$s</xliff:g> veut ajouter la tuile suivante au menu Paramètres rapides"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ajouter la tuile"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne pas ajouter tuile"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index cd4cfbd..91c05c6 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -1090,8 +1090,7 @@
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecture depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> sur <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Lire"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Ouvre <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Mets <xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Connexion automatique au Wi-Fi désactivée pour le moment"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Tout afficher"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Pour changer de réseau, déconnectez l\'Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Pour améliorer l\'expérience sur l\'appareil, les applis et les services peuvent continuer de rechercher les réseaux Wi-Fi, même si le Wi-Fi est désactivé. Vous pouvez modifier cela dans les paramètres de recherche Wi-Fi. "<annotation id="link">"Modifier"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> veut ajouter le bloc suivant aux Réglages rapides"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ajouter un bloc"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne pas ajouter bloc"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index b10090c..d4fd046 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"De momento, a wifi non se conectará automaticamente"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Ver todo"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para cambiar de rede, desconecta a Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para mellorar a experiencia que ofrece o dispositivo, as aplicacións e os servizos poden seguir buscando redes wifi en calquera momento, aínda que esta conexión estea desactivada. Podes cambiar esta opción na configuración da función Busca de redes wifi. "<annotation id="link">"Cambiar"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> solicita a túa aprobación para engadir o seguinte atallo a Configuración rápida"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Engadir atallo"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Non engadir atallo"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index d440222..8733604 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -1090,8 +1090,7 @@
<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="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચાલી રહ્યું છે"</string>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>માંથી <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</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="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચલાવો"</string>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"હમણાં પૂરતું વાઇ-ફાઇ ઑટોમૅટિક રીતે કનેક્ટ થશે નહીં"</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">"ડિવાઇસના અનુભવને બહેતર બનાવવા માટે, વાઇ-ફાઇ બંધ હોય ત્યારે પણ ઍપ અને સેવાઓ કોઈપણ સમયે વાઇ-ફાઇ નેટવર્ક સ્કૅન કરી શકે છે. તમે વાઇ-ફાઇ સ્કૅનિંગના સેટિંગમાં જઈને આને બદલી શકો છો. "<annotation id="link">"બદલો"</annotation></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>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 0b945f0..ff3bd7f 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"फ़िलहाल, वाई-फ़ाई अपने-आप कनेक्ट नहीं होगा"</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">"डिवाइस इस्तेमाल करने के अनुभव काे बेहतर बनाने के लिए, ऐप्लिकेशन और सेवाओं की मदद से, किसी भी समय वाई-फ़ाई नेटवर्क स्कैन किए जा सकते हैं. ऐसा वाई-फ़ाई बंद होने पर भी किया जा सकता है. वाई-फ़ाई स्कैनिंग की सेटिंग में जाकर, इसे बदला जा सकता है. "<annotation id="link">"बदलें"</annotation></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>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 731d00a..1acb156 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -1185,6 +1185,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi se zasad neće automatski povezivati"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Prikaži sve"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Da biste se prebacili na drugu mrežu, odspojite Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Da bi se poboljšao doživljaj uređaja, aplikacije i usluge i dalje mogu tražiti Wi-Fi mreže u bilo kojem trenutku, čak i kada je Wi-Fi isključen. To možete promijeniti u postavkama traženja Wi-Fija. "<annotation id="link">"Promijeni"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> želi dodati sljedeću pločicu u Brze postavke"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj pločicu"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nemoj dodati pločicu"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 2ebd1458..9986abe 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"A Wi-Fi-re történő csatlakozás jelenleg nem automatikus"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Megtekintés"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Hálózatváltáshoz válassza le az ethernetet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Az eszközhasználati élmény javítása érdekében az alkalmazások és a szolgáltatások továbbra is bármikor kereshetnek Wi-Fi-hálózatokat, még akkor is, ha a Wi-Fi ki van kapcsolva. A funkciót a „Wi-Fi scanning settings” (Wi-Fi-keresési beállítások) részben módosíthatja. "<annotation id="link">"Módosítás"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> a következő mozaikot szeretné hozzáadni a Gyorsbeállításokhoz"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Mozaik hozzáadása"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne legyen hozzáadva"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 735eedd..25931bf 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi-ն ավտոմատ չի միանա"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Տեսնել բոլորը"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Մի ցանցից մյուսին անցնելու համար անջատեք Ethernet-ը"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Սարքի աշխատանքը բարելավելու համար հավելվածներն ու ծառայությունները կորոնեն Wi‑Fi ցանցեր, նույնիսկ երբ Wi‑Fi-ն անջատված է։ Այս պարամետրը կարող եք փոխել Wi‑Fi ցանցերի որոնման կարգավորումներում։ "<annotation id="link">"Փոխել"</annotation></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>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index cc514c0..b197f62 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi tidak akan otomatis terhubung untuk saat ini"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Lihat semua"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Untuk beralih jaringan, lepaskan kabel ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Agar pengalaman perangkat menjadi lebih baik, aplikasi dan layanan tetap dapat memindai jaringan Wi-Fi kapan saja, bahkan saat Wi-Fi nonaktif. Anda dapat mengubahnya di setelan pemindaian Wi-Fi. "<annotation id="link">"Ubah"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ingin menambahkan kartu berikut ke Setelan Cepat"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tambahkan kartu"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Jangan tambah kartu"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 0491d8c..8ae27dc 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi tengist ekki sjálfkrafa eins og er"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Sjá allt"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Aftengdu ethernet til að skipta um net"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Til að bæta tækjaupplifun geta forrit og þjónustur áfram leitað að WiFi-netum hvenær sem er, jafnvel þótt slökkt sé á WiFi. Hægt er að breyta þessu í stillingum WiFi-leitar. "<annotation id="link">"Breyta"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vill bæta eftirfarandi reit við flýtistillingar"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Bæta reit við"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ekki bæta reit við"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 8aaf77d..96fc861 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Connessione automatica rete Wi-Fi non attiva al momento"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Mostra tutte"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Per cambiare rete, scollega il cavo Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Per migliorare l\'esperienza con il dispositivo, le app e i servizi possono continuare a cercare reti Wi-Fi in qualsiasi momento, anche quando la connessione Wi-Fi non è attiva. Puoi modificare questa preferenza nelle impostazioni relative alla ricerca di reti Wi-Fi. "<annotation id="link">"Cambia"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vuole aggiungere il seguente riquadro alle Impostazioni rapide"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Aggiungi riquadro"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Non aggiungerlo"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 9ec4103..2ecf51d 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -1191,6 +1191,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"ה-Wi-Fi לא יתחבר באופן אוטומטי בינתיים"</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">"כדי לשפר את חוויית השימוש במכשיר, אפליקציות ושירותים יוכלו לחפש רשתות Wi-Fi בכל שלב, גם כאשר ה-Wi-Fi כבוי. אפשר לשנות זאת בהגדרות של חיפוש נקודות Wi-Fi. "<annotation id="link">"שינוי"</annotation></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>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 520b048..74cc6be 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi に自動接続しません"</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">"デバイスの機能向上のため、アプリやサービスは、Wi-Fi が OFF の場合でも、いつでも Wi-Fi ネットワークをスキャンできます。この設定は Wi-Fi スキャンの設定で変更できます。"<annotation id="link">"変更"</annotation></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>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index de028b0..6596f6a 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi ინტერნეტს დროებით ავტომატურად არ დაუკავშირდება"</string>
<string name="see_all_networks" msgid="3773666844913168122">"ყველას ნახვა"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"ქსელების გადასართავად, გაწყვიტეთ Ethernet-თან კავშირი"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"მოწყობილობისგან მიღებული გამოცდილების გასაუმჯობესებლად, აპებსა და სერვისებს მაინც შეუძლია სკანირება Wi‑Fi ქსელების აღმოსაჩენად, ნებისმიერ დროს, მაშინაც კი, როცა Wi‑Fi გამორთულია. ამის შეცვლა Wi-Fi სკანირების პარამეტრებში შეგიძლიათ. "<annotation id="link">"შეცვლა"</annotation></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>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index b1dad23..b347709 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Әзірше Wi-Fi автоматты түрде қосылмайды."</string>
<string name="see_all_networks" msgid="3773666844913168122">"Барлығын көру"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Желілерді ауыстыру үшін ethernet кабелін ажыратыңыз."</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Құрылғы жұмысын жақсарту үшін қолданбалар мен қызметтер Wi-Fi байланысы өшірулі кезде де Wi-Fi желілерін іздейді. Оны Wi-Fi іздеу параметрлерінен өзгерте аласыз. "<annotation id="link">"Өзгерту"</annotation></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>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 828c864..db0018d 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi នឹងមិនភ្ជាប់ដោយស្វ័យប្រវត្តិក្នុងពេលនេះទេ"</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">"ដើម្បីធ្វើឱ្យបទពិសោធន៍ប្រើប្រាស់ឧបករណ៍ប្រសើរឡើង កម្មវិធី និងសេវាកម្មនៅតែអាចស្កេនរកបណ្ដាញ Wi‑Fi បានគ្រប់ពេល ទោះបីជានៅពេលដែលបិទ Wi‑Fi ក៏ដោយ។ អ្នកអាចប្ដូរវាបាននៅក្នុងការកំណត់ការស្កេន Wi‑Fi។ "<annotation id="link">"ប្ដូរ"</annotation></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>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 67d6488..60bb5ec 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -1090,8 +1090,7 @@
<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="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ರಲ್ಲಿ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</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="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ"</string>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"ಸದ್ಯದ ಮಟ್ಟಿಗೆ ವೈ-ಫೈ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಕನೆಕ್ಟ್ ಆಗುವುದಿಲ್ಲ"</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">"ವೈ-ಫೈ ಆಫ್ ಇದ್ದಾಗಲೂ ಸಹ, ಸಾಧನದ ಅನುಭವವನ್ನು ಸುಧಾರಿಸಲು, ಆ್ಯಪ್ಗಳು ಮತ್ತು ಸೇವೆಗಳು ಯಾವಾಗ ಬೇಕಾದರೂ ಸಹ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳಿಗಾಗಿ ಸ್ಕ್ಯಾನ್ ಮಾಡಬಹುದು. ನೀವು ಇದನ್ನು ವೈ-ಫೈ ಸ್ಕ್ಯಾನಿಂಗ್ ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಬದಲಾಯಿಸಬಹುದು. "<annotation id="link">"ಬದಲಿಸಿ"</annotation></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>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 0f59303..01d3158 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"지금은 Wi-Fi가 자동으로 연결되지 않습니다."</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">"기기 환경을 개선하기 위해 Wi‑Fi가 꺼져 있을 때도 앱과 서비스에서 Wi‑Fi 네트워크를 검색할 수 있습니다. 이 설정은 Wi‑Fi 검색 설정에서 변경할 수 있습니다. "<annotation id="link">"변경"</annotation></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>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 6e4c97f..e5383c7 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi азырынча автоматтык түрдө туташпайт"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Баарын көрүү"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Башка тармактарга которулуу үчүн Ethernet кабелин ажыратыңыз"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Түзмөктүн колдонулушун жакшыртуу үчүн колдонмолор менен кызматтар Wi‑Fi өчүп турса да зымсыз тармактарды издей беришет. Аны Wi-Fi тармактарын издөө жөндөөлөрүнөн өзгөртө аласыз. "<annotation id="link">"Өзгөртүү"</annotation></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>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index e61e847..c75dbca 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi ຈະບໍ່ເຊື່ອມຕໍ່ອັດຕະໂນມັດສຳລັບຕອນນີ້"</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">"ເພື່ອປັບປຸງປະສົບການອຸປະກອນ, ແອັບ ແລະ ບໍລິການຍັງຄົງສາມາດສະແກນຫາເຄືອຂ່າຍ Wi‑Fi ຕອນໃດກໍໄດ້, ເຖິງແມ່ນວ່າຈະປິດ Wi‑Fi ໄວ້ກໍຕາມ. ທ່ານສາມາດປ່ຽນສິ່ງນີ້ໄດ້ໃນການຕັ້ງຄ່າການສະແກນ Wi‑Fi. "<annotation id="link">"ປ່ຽນ"</annotation></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>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index fc77acb..2d5a4c4 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -1191,6 +1191,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"„Wi-Fi“ šiuo metu nebus prijungtas automatiškai"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Žiūrėti viską"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Norėdami perjungti tinklus, atjunkite eternetą"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Kad pagerintų įrenginio funkcijas, programos ir paslaugos vis tiek gali bet kada nuskaityti ieškodamos „Wi‑Fi“ tinklų, net jei „Wi‑Fi“ išjungtas. Tai galite pakeisti „Wi-Fi“ nuskaitymo nustatymuose. "<annotation id="link">"Pakeisti"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ nori prie sparčiųjų nustatymų pridėti toliau pateiktą išklotinės elementą"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Pridėti išklotinės elementą"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepridėti išklotinės elemento"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index bfcb01d..c98bd79 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -1185,6 +1185,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi savienojums īslaicīgi netiks izveidots automātiski."</string>
<string name="see_all_networks" msgid="3773666844913168122">"Visu tīklu skatīšana"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Lai pārslēgtu tīklus, atvienojiet tīkla Ethernet vadu."</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Lai uzlabotu ierīces lietošanas iespējas, lietotnes un pakalpojumi joprojām varēs meklēt Wi‑Fi tīklus jebkurā laikā, pat ja Wi‑Fi būs izslēgts. Varat to mainīt Wi‑Fi meklēšanas iestatījumos. "<annotation id="link">"Mainīt"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> pieprasa atļauju pievienot tālāk norādīto elementu ātrajiem iestatījumiem"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Pievienot elementu"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepievienot elementu"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index a55fe97..1f22b69 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi нема да се поврзува автоматски засега"</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">"За да се подобри доживувањето на уредот, апликациите и услугите може сѐ уште да скенираат за Wi‑Fi мрежи во секое време, дури и кога Wi‑Fi е исклучено. Може да го промените ова во поставките за „Скенирање за Wi-Fi“. "<annotation id="link">"Промени"</annotation></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>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 8242d91..d448f04 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"വൈഫൈ ഇപ്പോൾ സ്വയമേവ കണക്റ്റ് ചെയ്യില്ല"</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">"ഉപകരണ അനുഭവം മെച്ചപ്പെടുത്താൻ, വൈഫൈ ഓഫാക്കിയിരിക്കുമ്പോൾ പോലും ആപ്പുകൾക്കും സേവനങ്ങൾക്കും വൈഫൈ നെറ്റ്വർക്കുകൾ കണ്ടെത്താൻ ഏത് സമയത്തും സ്കാൻ ചെയ്യാനാകും. നിങ്ങൾക്ക് ഇത് വൈഫൈ സ്കാനിംഗ് ക്രമീകരണത്തിൽ മാറ്റാം. "<annotation id="link">"മാറ്റുക"</annotation></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>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 6772aff..e8fbef3 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi-г одоогоор автоматаар холбохгүй"</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">"Төхөөрөмжийн туршлагыг сайжруулахын тулд аппууд болон үйлчилгээнүүд нь Wi-Fi сүлжээг хүссэн үедээ буюу Wi-Fi-г унтраалттай байсан ч скан хийх боломжтой хэвээр байна. Та үүнийг Wi-Fi скан хийх тохиргоонд өөрчлөх боломжтой. "<annotation id="link">"Өөрчлөх"</annotation></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>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 2cba8a0..1ab644d 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"सध्या वाय-फाय ऑटो-कनेक्ट होणार नाही"</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">"डिव्हाइसच्या अनुभवामध्ये सुधारणा करण्यासाठी, वाय-फाय बंद असले तरीही ॲप्स आणि सेवा या कधीही वाय-फाय नेटवर्क स्कॅन करू शकतात. तुम्ही हे वाय-फाय स्कॅनिंग सेटिंग्जमध्ये बदलू शकता. "<annotation id="link">"बदला"</annotation></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>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 461456b..0a4bd89 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi tidak akan disambungkan secara automatik buat masa ini"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Lihat semua"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Untuk menukar rangkaian, putuskan sambungan ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Untuk meningkatkan pengalaman peranti, apl dan perkhidmatan masih dapat melakukan imbasan untuk mengesan rangkaian Wi-Fi pada bila-bila masa, meskipun apabila Wi-Fi dimatikan. Anda boleh menukar tetapan ini dalam tetapan pengimbasan Wi-Fi. "<annotation id="link">"Tukar"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> mahu menambah jubin yang berikut kepada Tetapan Pantas"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tambahkan jubin"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Jangan tambah jubin"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 35e53a6..643bd01 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi က လောလောဆယ် အလိုအလျောက် ချိတ်ဆက်မည်မဟုတ်ပါ"</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">"စက်ပစ္စည်းကို ပိုမိုကောင်းမွန်စွာ အသုံးပြုနိုင်ရန် Wi-Fi ပိတ်ထားသည့်တိုင် အက်ပ်နှင့် ဝန်ဆောင်မှုများက Wi-Fi ကွန်ရက်များကို အချိန်မရွေး စကင်ဖတ်နိုင်သည်။ ၎င်းကို Wi-Fi ရှာဖွေခြင်း ဆက်တင်များတွင် ပြောင်းနိုင်သည်။ "<annotation id="link">"ပြောင်းရန်"</annotation></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>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index f99aaee..70529a6 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -1090,8 +1090,7 @@
<string name="controls_media_resume" msgid="1933520684481586053">"Gjenoppta"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Innstillinger"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> av <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spilles av fra <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> av <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Spill av"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Åpne <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Spill av <xliff:g id="SONG_NAME">%1$s</xliff:g> av <xliff:g id="ARTIST_NAME">%2$s</xliff:g> fra <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi kobles ikke til automatisk inntil videre"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Se alle"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"For å bytte nettverk, koble fra Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"For å forbedre brukeropplevelsen på enheten kan apper og tjenester søke etter Wi-Fi-nettverk når som helst – også når Wi-Fi er slått av. Du kan endre dette i innstillingene for Wi-Fi-skanning. "<annotation id="link">"Bytt"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vil legge til denne brikken i Hurtiginnstillinger"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Legg til brikke"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ikke legg til brikke"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index f061507..d75bb1b 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"केही समयका लागि Wi-Fi स्वतः कनेक्ट हुँदैन"</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">"डिभाइस प्रयोगको अनुभवमा गुणस्तर सुधार गर्न, एप तथा सेवाहरूले अझै पनि जुनसुकै बेला (Wi‑Fi अफ भएका बेलामा पनि) Wi‑Fi नेटवर्क खोज्न सक्छन्। तपाईं यसलाई Wi‑Fi स्क्यानिङका सेटिङमा गई परिवर्तन गर्न सक्नुहुन्छ। "<annotation id="link">"बदल्नुहोस्"</annotation></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>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 756141e..cf72f0c 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wifi maakt momenteel niet automatisch verbinding"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Alles tonen"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Verbreek de ethernetverbinding om van netwerk te wisselen"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Apps en services kunnen nog steeds op elk moment scannen op wifi-netwerken, zelfs als wifi uitstaat, om de apparaatfunctionaliteit te verbeteren. Je kunt dit aanpassen in de instellingen voor wifi-scannen. "<annotation id="link">"Wijzigen"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wil de volgende tegel toevoegen aan Snelle instellingen"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tegel toevoegen"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Tegel niet toevoegen"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index e336c38..6821f8c 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -1090,8 +1090,7 @@
<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="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>ରୁ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</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="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚଲାନ୍ତୁ"</string>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"ବର୍ତ୍ତମାନ ପାଇଁ ୱାଇ-ଫାଇ ସ୍ୱତଃ-ସଂଯୋଗ ହେବ ନାହିଁ"</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">"ଡିଭାଇସ ଅନୁଭୂତିକୁ ଉନ୍ନତ କରିବା ପାଇଁ, ୱାଇ-ଫାଇ ବନ୍ଦ ଥିଲେ ମଧ୍ୟ ଆପ ଓ ସେବାଗୁଡ଼ିକ ଏବେ ବି ଯେ କୌଣସି ସମୟରେ ୱାଇ-ଫାଇ ନେଟୱାର୍କ ପାଇଁ ସ୍କାନ କରିପାରିବ। ଆପଣ ଏହାକୁ ୱାଇ-ଫାଇ ସ୍କାନିଂ ସେଟିଂସରେ ପରିବର୍ତ୍ତନ କରିପାରିବେ। "<annotation id="link">"ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</annotation></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>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index cc20ab7..ee748a8 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"ਫ਼ਿਲਹਾਲ ਵਾਈ-ਫਾਈ ਸਵੈ-ਕਨੈਕਟ ਨਹੀਂ ਹੋਵੇਗਾ"</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">"ਡੀਵਾਈਸ ਦੇ ਅਨੁਭਵ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ, ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਕਿਸੇ ਵੀ ਸਮੇਂ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ ਲਈ ਸਕੈਨ ਕਰ ਸਕਦੀਆਂ ਹਨ, ਭਾਵੇਂ ਵਾਈ-ਫਾਈ ਬੰਦ ਹੀ ਕਿਉਂ ਨਾ ਹੋਵੇ। ਤੁਸੀਂ ਇਸ ਨੂੰ ਵਾਈ‑ਫਾਈ ਸਕੈਨਿੰਗ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਬਦਲ ਸਕਦੇ ਹੋ। "<annotation id="link">"ਬਦਲੋ"</annotation></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>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index b4fb410..ac2d489 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -1191,6 +1191,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi nie będzie na razie włączać się automatycznie"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Pokaż wszystko"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Aby przełączać sieci, odłącz Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Aby zapewnić Ci większy komfort korzystania z urządzenia, aplikacje i usługi mogą nadal wyszukiwać sieci Wi-Fi w pobliżu nawet wtedy, gdy Wi-Fi jest wyłączone. Możesz to zmienić w ustawieniach skanowania Wi-Fi. "<annotation id="link">"Zmień"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"Aplikacja <xliff:g id="APPNAME">%1$s</xliff:g> chce dodać do Szybkich ustawień ten kafelek"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj kafelek"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nie dodawaj kafelka"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index f03525d..6a67522 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"A conexão automática ao Wi-Fi ficará indisponível"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Ver tudo"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para mudar de rede, desconecte o cabo Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para melhorar a experiência no dispositivo, os apps e serviços ainda podem procurar redes Wi-Fi a qualquer momento, mesmo quando o Wi-Fi estiver desativado. Você pode mudar essa opção nas configurações de busca por Wi-Fi. "<annotation id="link">"Mudar"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"O app <xliff:g id="APPNAME">%1$s</xliff:g> quer adicionar o bloco a seguir às Configurações rápidas"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adicionar bloco"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Não adicionar bloco"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index f49627f..6225ae4 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Por agora, o Wi-Fi não irá estabelecer lig. automaticamente"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Veja tudo"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para mudar de rede, desligue a Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para melhorar a experiência do dispositivo, as apps e os serviços podem continuar a procurar redes Wi-Fi em qualquer altura, mesmo quando o Wi-Fi está desativado. Pode alterar esta opção nas definições de procura de Wi-Fi. "<annotation id="link">"Alterar"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"A app <xliff:g id="APPNAME">%1$s</xliff:g> pretende adicionar o seguinte mosaico às Definições rápidas"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adicionar mosaico"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Não adicion. mosaico"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index f03525d..6a67522 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"A conexão automática ao Wi-Fi ficará indisponível"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Ver tudo"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para mudar de rede, desconecte o cabo Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para melhorar a experiência no dispositivo, os apps e serviços ainda podem procurar redes Wi-Fi a qualquer momento, mesmo quando o Wi-Fi estiver desativado. Você pode mudar essa opção nas configurações de busca por Wi-Fi. "<annotation id="link">"Mudar"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"O app <xliff:g id="APPNAME">%1$s</xliff:g> quer adicionar o bloco a seguir às Configurações rápidas"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adicionar bloco"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Não adicionar bloco"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 978c222..a09779d 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -1185,6 +1185,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Deocamdată, Wi-Fi nu se poate conecta automat"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Afișează-le pe toate"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Pentru a schimba rețeaua, deconectați ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Pentru a îmbunătăți experiența cu dispozitivul, aplicațiile și serviciile pot să caute în continuare rețele Wi‑Fi chiar și atunci când conexiunea Wi-Fi este dezactivată. Puteți să schimbați acest aspect din setările pentru căutarea de rețele Wi-Fi. "<annotation id="link">"Schimbați"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vrea să adauge următorul card la Setări rapide"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adăugați un card"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nu adăugați un card"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 35366df..1b6e85b 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -1191,6 +1191,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Подключение по Wi-Fi не установится автоматически."</string>
<string name="see_all_networks" msgid="3773666844913168122">"Показать все"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Чтобы переключиться между сетями, отключите кабель Ethernet."</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Чтобы улучшать работу устройства, приложения и сервисы могут искать беспроводные сети в любое время, даже если вы отключили Wi‑Fi. Чтобы запретить это, отключите поиск сетей Wi‑Fi. "<annotation id="link">"Открыть настройки"</annotation></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>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index f6bb208..94d8705 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi දැනට ස්වයං-සබැඳි නොවනු ඇත"</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">"උපාංග අත්දැකීම වැඩි දියුණු කිරිමට, Wi‑Fi ක්රියාවිරහිත විට පවා, ඕනෑම අවස්ථාවක Wi‑Fi ජාල සඳහා ස්කෑන් කිරීමට යෙදුම් සහ සේවාවලට හැකිය. ඔබට මෙය Wi‑Fi ස්කෑන් කිරීමේ සැකසීම් තුළ වෙනස් කළ හැකිය. "<annotation id="link">"වෙනස් කරන්න"</annotation></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>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c349ef1..a0ba5cd 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -1191,6 +1191,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi‑Fi sa teraz automaticky nepripojí"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Zobraziť všetko"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Ak chcete prepnúť siete, odpojte ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Aplikácie a služby môžu kedykoľvek vyhľadávať siete Wi‑Fi (a to aj vtedy, keď je pripojenie Wi‑Fi vypnuté), čím zlepšujú prostredie v zariadení. Môžete to zmeniť v nastaveniach vyhľadávania sietí Wi‑Fi. "<annotation id="link">"Zmeniť"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"Aplikácia <xliff:g id="APPNAME">%1$s</xliff:g> chce pridať do rýchlych nastavení túto kartu"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Pridať kartu"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepridať kartu"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index d41459a..649e123 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -1191,6 +1191,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Vmesnik Wi-Fi trenutno ne bo samodejno vzpostavil povezave."</string>
<string name="see_all_networks" msgid="3773666844913168122">"Prikaz vseh omrežij"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Če želite preklopiti omrežje, prekinite ethernetno povezavo."</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Za izboljšano izkušnjo pri uporabi naprave lahko aplikacije in storitve kadar koli iščejo omrežja Wi‑Fi, tudi ko je Wi‑Fi izklopljen. To lahko spremenite v nastavitvah iskanja omrežij Wi-Fi. "<annotation id="link">"Spremeni"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> želi dodati to ploščico v hitre nastavitve."</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj ploščico"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne dodaj ploščice"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index e4ec008..f5c30dd 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi nuk do të lidhet automatikisht për momentin"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Shiko të gjitha"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Për të ndërruar rrjetet, shkëput Ethernet-in"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Për të përmirësuar përvojën e pajisjes, aplikacionet dhe shërbimet mund të vazhdojnë të skanojnë për rrjete Wi-Fi në çdo kohë, edhe kur Wi-Fi është joaktiv. Mund ta ndryshosh këtë te cilësimet e skanimit të Wi-Fi. "<annotation id="link">"Ndrysho"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> dëshiron të shtojë pllakëzën e mëposhtme te \"Cilësimet e shpejta\""</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Shto një pllakëz"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Mos e shto pllakëzën"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 3dbda9b..bcd7bc8 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -1185,6 +1185,7 @@
<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="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>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index eccf9ee..45666a2 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Du ansluts inte till wifi automatiskt för närvarande"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Visa alla"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Koppla bort Ethernet för att växla nätverk"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"I syfte att förbättra upplevelsen med enheten kan appar och tjänster fortfarande söka efter wifi-nätverk när som helst, även om wifi har inaktiverats. "<annotation id="link">"Ändra"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vill lägga till följande ruta i snabbinställningarna"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Lägg till ruta"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Lägg inte till ruta"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 31f74b2..e976c92 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi haitaunganishwa kiotomatiki kwa sasa"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Angalia yote"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Ili kubadili mitandao, tenganisha ethaneti"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Ili kuboresha hali ya matumizi ya kifaa, programu na huduma bado zinaweza kutafuta mitandao ya Wi‑Fi wakati wowote, hata wakati umezima Wi‑Fi. Unaweza kubadilisha mipangilio hii katika mipangilio ya kutafuta Wi-Fi. "<annotation id="link">"Badilisha"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ingependa kuongeza kigae kifuatacho kwenye Mipangilio ya Haraka"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ongeza kigae"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Usiongeze kigae"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index f2d2254..bfe399d 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"தற்போதைக்கு வைஃபை தானாக இணைக்கப்படாது"</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">"சாதன அனுபவத்தை மேம்படுத்த, வைஃபை ஆஃப் செய்யப்பட்டிருந்தாலும்கூட எந்த நேரத்திலும் ஆப்ஸும் சேவைகளும் வைஃபை நெட்வொர்க்குகளைத் தேடலாம். வைஃபை ஸ்கேனிங் அமைப்புகளில் இதை மாற்றிக் கொள்ளலாம். "<annotation id="link">"மாற்று"</annotation></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>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index be277b1..e6d7de9 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -563,30 +563,30 @@
<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="5749932930634037027">"మీరు <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
- <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"మీరు ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <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="368812367182387320">"మీ కార్యాలయ ప్రొఫైల్ ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది."</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"మీ వ్యక్తిగత ప్రొఫైల్ ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది."</string>
+ <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"మీరు <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"మీరు ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <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="368812367182387320">"మీ కార్యాలయ ప్రొఫైల్ ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"మీ వ్యక్తిగత ప్రొఫైల్ ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది."</string>
<string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"మీ పరికరం <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> ద్వారా నిర్వహించబడుతోంది."</string>
<string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> మీ పరికరాన్ని నిర్వహించడానికి <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g>ని ఉపయోగిస్తుంది."</string>
<string name="monitoring_description_do_body" msgid="7700878065625769970">"మీ పరికరంతో అనుబంధించబడిన సెట్టింగ్లు, కార్పొరేట్ యాక్సెస్, యాప్లు, డేటా మరియు మీ పరికరం యొక్క లొకేషన్ సమాచారాన్ని మీ అడ్మిన్ పర్యవేక్షించగలరు, మేనేజ్ చేయగలరు."</string>
<string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
<string name="monitoring_description_do_learn_more" msgid="645149183455573790">"మరింత తెలుసుకోండి"</string>
- <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"మీరు <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ వ్యక్తిగత నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
+ <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"మీరు <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ వ్యక్తిగత నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN సెట్టింగ్లను తెరవండి"</string>
<string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string>
<string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"విశ్వసనీయ ఆధారాలను తెరువు"</string>
<string name="monitoring_description_network_logging" msgid="577305979174002252">"మీ నిర్వాహకులు మీ పరికరంలోని ట్రాఫిక్ని పర్యవేక్షించగల నెట్వర్క్ లాగింగ్ని ఆన్ చేశారు.\n\nమరింత సమాచారం కావాలంటే, మీ నిర్వాహకులను సంప్రదించండి."</string>
- <string name="monitoring_description_vpn" msgid="1685428000684586870">"మీరు VPN కనెక్షన్ సెటప్ చేయడానికి ఒక యాప్నకు అనుమతి ఇచ్చారు.\n\nఈ యాప్ ఇమెయిల్లు,యాప్లు మరియు వెబ్సైట్లతో సహా మీ డివైజ్ మరియు నెట్వర్క్ యాక్టివిటీని పర్యవేక్షించగలదు."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ద్వారా మీ కార్యాలయ ప్రొఫైల్ నిర్వహించబడుతోంది.\n\nఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల సామర్థ్యం మీ నిర్వాహకులకు ఉంది.\n\nమరింత సమాచారం కావాలంటే, మీ నిర్వాహకులను సంప్రదించండి.\n\nమీరు VPNకి కూడా కనెక్ట్ అయ్యారు, ఇది మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
+ <string name="monitoring_description_vpn" msgid="1685428000684586870">"మీరు VPN కనెక్షన్ సెటప్ చేయడానికి ఒక యాప్నకు అనుమతి ఇచ్చారు.\n\nఈ యాప్ ఈమెయిళ్లు,యాప్లు మరియు వెబ్సైట్లతో సహా మీ డివైజ్ మరియు నెట్వర్క్ యాక్టివిటీని పర్యవేక్షించగలదు."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ద్వారా మీ కార్యాలయ ప్రొఫైల్ నిర్వహించబడుతోంది.\n\nఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల సామర్థ్యం మీ నిర్వాహకులకు ఉంది.\n\nమరింత సమాచారం కావాలంటే, మీ నిర్వాహకులను సంప్రదించండి.\n\nమీరు VPNకి కూడా కనెక్ట్ అయ్యారు, ఇది మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ఈ పరికరాన్ని మీ తల్లి/తండ్రి మేనేజ్ చేస్తున్నారు. మీ తల్లి/తండ్రి, మీరు ఉపయోగించే యాప్లు, మీ లొకేషన్, అలాగే మీ పరికర వినియోగ వ్యవధి వంటి సమాచారాన్ని చూడగలరు, మేనేజ్ చేయగలరు."</string>
<string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
- <string name="monitoring_description_app" msgid="376868879287922929">"మీరు ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు."</string>
- <string name="monitoring_description_app_personal" msgid="1970094872688265987">"మీరు <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ వ్యక్తిగత నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
- <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"మీరు <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ వ్యక్తిగత నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
- <string name="monitoring_description_app_work" msgid="3713084153786663662">"మీ కార్యాలయ ప్రొఫైల్ <xliff:g id="ORGANIZATION">%1$s</xliff:g> నిర్వహణలో ఉంది. ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ కార్యాలయ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION">%2$s</xliff:g>కి ప్రొఫైల్ కనెక్ట్ చేయబడింది.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
- <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"మీ కార్యాలయ ప్రొఫైల్ <xliff:g id="ORGANIZATION">%1$s</xliff:g> నిర్వహణలో ఉంది. ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ కార్యాలయ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>కి ప్రొఫైల్ కనెక్ట్ చేయబడింది.\n\nమీ వ్యక్తిగత నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>కి కూడా మీరు కనెక్ట్ చేయబడ్డారు."</string>
+ <string name="monitoring_description_app" msgid="376868879287922929">"మీరు ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు."</string>
+ <string name="monitoring_description_app_personal" msgid="1970094872688265987">"మీరు <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ వ్యక్తిగత నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
+ <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"మీరు <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ వ్యక్తిగత నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
+ <string name="monitoring_description_app_work" msgid="3713084153786663662">"మీ కార్యాలయ ప్రొఫైల్ <xliff:g id="ORGANIZATION">%1$s</xliff:g> నిర్వహణలో ఉంది. ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ కార్యాలయ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION">%2$s</xliff:g>కి ప్రొఫైల్ కనెక్ట్ చేయబడింది.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
+ <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"మీ కార్యాలయ ప్రొఫైల్ <xliff:g id="ORGANIZATION">%1$s</xliff:g> నిర్వహణలో ఉంది. ఈమెయిళ్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ కార్యాలయ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>కి ప్రొఫైల్ కనెక్ట్ చేయబడింది.\n\nమీ వ్యక్తిగత నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>కి కూడా మీరు కనెక్ట్ చేయబడ్డారు."</string>
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ద్వారా అన్లాక్ చేయబడింది"</string>
<string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"మీరు మాన్యువల్గా అన్లాక్ చేస్తే మినహా పరికరం లాక్ చేయబడి ఉంటుంది"</string>
<string name="keyguard_indication_trust_unlocked_plugged_in" msgid="2323452175329362855">"<xliff:g id="KEYGUARD_INDICATION">%1$s</xliff:g>\n<xliff:g id="POWER_INDICATION">%2$s</xliff:g>"</string>
@@ -611,7 +611,7 @@
<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_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>
@@ -844,7 +844,7 @@
<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_email" msgid="7852376788894975192">"ఈమెయిల్"</string>
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"మ్యూజిక్"</string>
<string name="keyboard_shortcut_group_applications_youtube" msgid="5078136084632450333">"YouTube"</string>
@@ -1090,8 +1090,7 @@
<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="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి ప్లే అవుతోంది"</string>
- <!-- no translation found for controls_media_seekbar_description (4389621713616214611) -->
- <skip />
+ <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>లో <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</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="APP_LABEL">%3$s</xliff:g> నుండి <xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g>ను ప్లే చేయండి"</string>
@@ -1180,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"ప్రస్తుతానికి Wi-Fi ఆటోమేటిక్గా కనెక్ట్ అవ్వదు"</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">"పరికర అనుభవాన్ని మెరుగుపరచడానికి, Wi‑Fi ఆఫ్లో ఉన్నప్పుడు కూడా, ఏ సమయంలో అయినా ఇప్పటికీ Wi‑Fi నెట్వర్క్ల కోసం యాప్లు, సర్వీస్లు స్కాన్ చేయగలవు. మీరు దీనిని Wi‑Fi స్కానింగ్ సెట్టింగ్లలో మార్చవచ్చు. "<annotation id="link">"మార్చండి"</annotation></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>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index f7811fb..55329bd 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi จะไม่เชื่อมต่ออัตโนมัติในตอนนี้"</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">"เพื่อปรับปรุงประสบการณ์การใช้อุปกรณ์ แอปและบริการต่างๆ จะยังคงสแกนหาเครือข่าย Wi‑Fi ได้ทุกเมื่อแม้ว่า Wi‑Fi จะปิดอยู่ คุณเปลี่ยนตัวเลือกนี้ได้ในการตั้งค่าการสแกนหา Wi-Fi "<annotation id="link">"เปลี่ยน"</annotation></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>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 822a3fd..264632b 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Hindi awtomatikong kokonekta ang Wi-Fi sa ngayon"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Tingnan lahat"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para lumipat ng network, idiskonekta ang ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para pahusayin ang karanasan sa device, puwede pa ring mag-scan ng mga Wi-Fi network ang mga app at serbisyo anumang oras, kahit habang naka-off ang Wi‑Fi. Mababago mo ito sa mga setting ng pag-scan ng Wi-Fi. "<annotation id="link">"Baguhin"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"Gustong idagdag ng <xliff:g id="APPNAME">%1$s</xliff:g> ang sumusunod na tile sa Mga Mabilisang Setting"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Idagdag ang tile"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Huwag idagdag"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 3849727..c691440 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Şu anda kablosuz ağa otomatik olarak bağlanılamıyor"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Tümünü göster"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Ağ değiştirmek için ethernet bağlantısını kesin"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Uygulamalar ve hizmetler, cihaz deneyimini iyileştirmek için Kablosuz özelliği kapalı bile olsa kablosuz ağlar herhangi bir zamanda tarayabilir. Bunu kablosuz ağ taraması ayarlarından değiştirebilirsiniz. "<annotation id="link">"Değiştir"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> aşağıdaki kartı Hızlı Ayarlar\'a eklemek istiyor"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Kart ekle"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Kart ekleme"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 51cc6dd..57b9d8a 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -1191,6 +1191,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Пристрій не підключатиметься до Wi-Fi автоматично"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Показати все"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Щоб вибрати іншу мережу, від’єднайте кабель Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Щоб користуватися пристроєм було зручніше, додатки й сервіси можуть шукати бездротові мережі, навіть якщо Wi-Fi вимкнено. Це налаштування можна змінити в параметрах пошуку мереж Wi-Fi. "<annotation id="link">"Змінити"</annotation></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>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 0690b5f..788b162 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"ابھی Wi-Fi خود کار طور پر منسلک نہیں ہوگا"</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">"آلے کے تجربے کو بہتر بنانے کے لیے، Wi‑Fi کے آف ہونے پر بھی ایپس اور سروسز کسی بھی وقت Wi‑Fi نیٹ ورکس اسکین کر سکتی ہیں۔ آپ اسے Wi‑Fi اسکیننگ کی ترتیبات میں تبدیل کر سکتے ہیں۔ "<annotation id="link">"تبدیل کریں"</annotation></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>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index acda73d..1be13be 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi hozir avtomatik ulanmaydi"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Hammasi"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Boshqa tarmoqqa almashish uchun Ethernet tarmogʻini uzing"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Qurilma ishlashini yaxshilash uchun ilova va xizmatlar hatto Wi-Fi yoqilmaganda ham istalgan vaqt Wi-Fi tarmoqlarni qidirishi mumkin. Buni taqiqlash uchun Wi-Fi tarmoqlarni qidirish funksiyasini faolsizlantiring. "<annotation id="link">"Sozlamalarni ochish"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ilovasi Tezkor sozlamalarga quyidagi tugmani kiritmoqchi"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tugma kiritish"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Tugma kiritilmasin"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 2679b00..2478ca4 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Tạm thời, Wi-Fi sẽ không tự động kết nối"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Xem tất cả"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Để chuyển mạng, hãy rút cáp Ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Để cải thiện trải nghiệm khi dùng thiết bị, các ứng dụng và dịch vụ vẫn có thể quét tìm mạng Wi‑Fi bất cứ lúc nào, ngay cả khi Wi‑Fi tắt. Bạn có thể thay đổi chế độ này trong phần cài đặt tính năng Quét tìm Wi‑Fi. "<annotation id="link">"Thay đổi"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> muốn thêm ô bên dưới vào trình đơn Cài đặt nhanh"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Thêm ô"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Không thêm ô"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 8ca914d..e6421a2 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"WLAN 暂时无法自动连接"</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">"为了提升设备的使用体验,即使 WLAN 已关闭,应用和服务仍可以随时扫描 WLAN 网络。您可以在 WLAN 扫描设置中更改此设置。"<annotation id="link">"更改"</annotation></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>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index e1c3b35..f94a46a 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"目前系統不會自動連線至 Wi-Fi"</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">"為改善裝置的使用體驗,應用程式和服務仍可隨時掃瞄 Wi-Fi 網絡 (即使 Wi-Fi 已關閉)。您可在 Wi-Fi 掃瞄設定中變更此設定。"<annotation id="link">"變更"</annotation></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>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 66434e4..48c6cda 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"目前不會自動連上 Wi-Fi"</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">"為提升裝置的使用體驗,應用程式和服務仍可隨時掃描 Wi‑Fi 網路,即使 Wi-Fi 連線功能處於關閉狀態時亦然。你可以前往「掃描 Wi-Fi」設定進行變更。"<annotation id="link">"變更"</annotation></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>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 6505503..de88b05 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -1179,6 +1179,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"I-Wi-Fi ngeke ixhume ngokuzenzakalelayo okwamanje"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Bona konke"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Ukuze ushintshe amanethiwekhi, nqamula i-ethernet"</string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Ukuze kuthuthukiswe ukuzizwela kwedivayisi, ama-app namasevisi kusengakwazi ukuskena amanethiwekhi we-Wi-Fi noma kunini, ngisho noma i-Wi-Fi ivaliwe, Ungashintsha lokhu kumasethingi Wokuskena i-Wi-Fi. "<annotation id="link">"Shintsha"</annotation></string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"I-<xliff:g id="APPNAME">%1$s</xliff:g> ifuna ukwengeza ithayela elilandelayo Kumasethingi Asheshayo"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Engeza ithayela"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ungafaki ithayela"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index c2901a5..2eaf098 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -723,6 +723,30 @@
<!-- Timeout to idle mode duration in milliseconds. -->
<integer name="config_idleModeTimeout">10000</integer>
+ <!-- This value is used when calculating whether the device is in ambient light mode. It is
+ light mode when the light sensor sample value exceeds above this value. -->
+ <integer name="config_ambientLightModeThreshold">5</integer>
+
+ <!-- This value is used when calculating whether the device is in ambient dark mode. It is
+ dark mode when the light sensor sample value drops below this value. -->
+ <integer name="config_ambientDarkModeThreshold">2</integer>
+
+ <!-- This value is used when calculating whether the device is in ambient light mode. Each
+ sample contains light sensor events from this span of time duration. -->
+ <integer name="config_ambientLightModeSamplingSpanMillis">10000</integer>
+
+ <!-- This value is used when calculating whether the device is in ambient dark mode. Each
+ sample contains light sensor events from this span of time duration. -->
+ <integer name="config_ambientDarkModeSamplingSpanMillis">2000</integer>
+
+ <!-- This value is used when calculating whether the device is in ambient light mode. The
+ samples are collected at this frequency. -->
+ <integer name="config_ambientLightModeSamplingFrequencyMillis">1000</integer>
+
+ <!-- This value is used when calculating whether the device is in ambient dark mode. The
+ samples are collected at this frequency. -->
+ <integer name="config_ambientDarkModeSamplingFrequencyMillis">500</integer>
+
<!-- The maximum number of attempts to reconnect to the communal source target after failing
to connect -->
<integer name="config_communalSourceMaxReconnectAttempts">10</integer>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt
new file mode 100644
index 0000000..e072d41
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt
@@ -0,0 +1,73 @@
+package com.android.systemui.unfold.util
+
+import android.content.Context
+import android.os.RemoteException
+import android.util.Log
+import android.view.IRotationWatcher
+import android.view.IWindowManager
+import android.view.Surface
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+
+/**
+ * [UnfoldTransitionProgressProvider] that emits transition progress only when the display has
+ * default rotation or 180 degrees opposite rotation (ROTATION_0 or ROTATION_180).
+ * It could be helpful to run the animation only when the display's rotation is perpendicular
+ * to the fold.
+ */
+class NaturalRotationUnfoldProgressProvider(
+ private val context: Context,
+ private val windowManagerInterface: IWindowManager,
+ unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider
+) : UnfoldTransitionProgressProvider {
+
+ private val scopedUnfoldTransitionProgressProvider =
+ ScopedUnfoldTransitionProgressProvider(unfoldTransitionProgressProvider)
+ private val rotationWatcher = RotationWatcher()
+
+ private var isNaturalRotation: Boolean = false
+
+ fun init() {
+ try {
+ windowManagerInterface.watchRotation(rotationWatcher, context.display.displayId)
+ } catch (e: RemoteException) {
+ throw e.rethrowFromSystemServer()
+ }
+
+ onRotationChanged(context.display.rotation)
+ }
+
+ private fun onRotationChanged(rotation: Int) {
+ val isNewRotationNatural = rotation == Surface.ROTATION_0 ||
+ rotation == Surface.ROTATION_180
+
+ if (isNaturalRotation != isNewRotationNatural) {
+ isNaturalRotation = isNewRotationNatural
+ scopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(isNewRotationNatural)
+ }
+ }
+
+ override fun destroy() {
+ try {
+ windowManagerInterface.removeRotationWatcher(rotationWatcher)
+ } catch (e: RemoteException) {
+ e.rethrowFromSystemServer()
+ }
+
+ scopedUnfoldTransitionProgressProvider.destroy()
+ }
+
+ override fun addCallback(listener: TransitionProgressListener) {
+ scopedUnfoldTransitionProgressProvider.addCallback(listener)
+ }
+
+ override fun removeCallback(listener: TransitionProgressListener) {
+ scopedUnfoldTransitionProgressProvider.removeCallback(listener)
+ }
+
+ private inner class RotationWatcher : IRotationWatcher.Stub() {
+ override fun onRotationChanged(rotation: Int) {
+ this@NaturalRotationUnfoldProgressProvider.onRotationChanged(rotation)
+ }
+ }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.java b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.java
new file mode 100644
index 0000000..543232d
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.java
@@ -0,0 +1,142 @@
+/*
+ * 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.systemui.unfold.util;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Manages progress listeners that can have smaller lifespan than the unfold animation.
+ * Allows to limit getting transition updates to only when
+ * {@link ScopedUnfoldTransitionProgressProvider#setReadyToHandleTransition} is called
+ * with readyToHandleTransition = true
+ *
+ * If the transition has already started by the moment when the clients are ready to play
+ * the transition then it will report transition started callback and current animation progress.
+ */
+public final class ScopedUnfoldTransitionProgressProvider implements
+ UnfoldTransitionProgressProvider, TransitionProgressListener {
+
+ private static final float PROGRESS_UNSET = -1f;
+
+ @Nullable
+ private UnfoldTransitionProgressProvider mSource;
+
+ private final List<TransitionProgressListener> mListeners = new ArrayList<>();
+
+ private boolean mIsReadyToHandleTransition;
+ private boolean mIsTransitionRunning;
+ private float mLastTransitionProgress = PROGRESS_UNSET;
+
+ public ScopedUnfoldTransitionProgressProvider() {
+ this(null);
+ }
+
+ public ScopedUnfoldTransitionProgressProvider(
+ @Nullable UnfoldTransitionProgressProvider source) {
+ setSourceProvider(source);
+ }
+
+ /**
+ * Sets the source for the unfold transition progress updates,
+ * it replaces current provider if it is already set
+ * @param provider transition provider that emits transition progress updates
+ */
+ public void setSourceProvider(@Nullable UnfoldTransitionProgressProvider provider) {
+ if (mSource != null) {
+ mSource.removeCallback(this);
+ }
+
+ if (provider != null) {
+ mSource = provider;
+ mSource.addCallback(this);
+ } else {
+ mSource = null;
+ }
+ }
+
+ /**
+ * Allows to notify this provide whether the listeners can play the transition or not.
+ * Call this method with readyToHandleTransition = true when all listeners
+ * are ready to consume the transition progress events.
+ * Call it with readyToHandleTransition = false when listeners can't process the events.
+ */
+ public void setReadyToHandleTransition(boolean isReadyToHandleTransition) {
+ if (mIsTransitionRunning) {
+ if (isReadyToHandleTransition) {
+ mListeners.forEach(TransitionProgressListener::onTransitionStarted);
+
+ if (mLastTransitionProgress != PROGRESS_UNSET) {
+ mListeners.forEach(listener ->
+ listener.onTransitionProgress(mLastTransitionProgress));
+ }
+ } else {
+ mIsTransitionRunning = false;
+ mListeners.forEach(TransitionProgressListener::onTransitionFinished);
+ }
+ }
+
+ mIsReadyToHandleTransition = isReadyToHandleTransition;
+ }
+
+ @Override
+ public void addCallback(@NonNull TransitionProgressListener listener) {
+ mListeners.add(listener);
+ }
+
+ @Override
+ public void removeCallback(@NonNull TransitionProgressListener listener) {
+ mListeners.remove(listener);
+ }
+
+ @Override
+ public void destroy() {
+ mSource.removeCallback(this);
+ }
+
+ @Override
+ public void onTransitionStarted() {
+ this.mIsTransitionRunning = true;
+ if (mIsReadyToHandleTransition) {
+ mListeners.forEach(TransitionProgressListener::onTransitionStarted);
+ }
+ }
+
+ @Override
+ public void onTransitionProgress(float progress) {
+ if (mIsReadyToHandleTransition) {
+ mListeners.forEach(listener -> listener.onTransitionProgress(progress));
+ }
+
+ mLastTransitionProgress = progress;
+ }
+
+ @Override
+ public void onTransitionFinished() {
+ if (mIsReadyToHandleTransition) {
+ mListeners.forEach(TransitionProgressListener::onTransitionFinished);
+ }
+
+ mIsTransitionRunning = false;
+ mLastTransitionProgress = PROGRESS_UNSET;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 94b1728..3c80a18 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -695,8 +695,11 @@
private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
@Override
public void onAllAuthenticatorsRegistered() {
- updateIsUdfpsEnrolled();
- updateConfiguration();
+ // must be called from the main thread since it may update the views
+ mExecutor.execute(() -> {
+ updateIsUdfpsEnrolled();
+ updateConfiguration();
+ });
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index 2f88291..294d1f4 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -174,7 +174,8 @@
mReceiver,
mReceiver.createIntentFilter(),
PERMISSION_SELF,
- null);
+ null,
+ Context.RECEIVER_EXPORTED);
registerActions();
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
index 5f75d86..31dd82d 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
+++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
@@ -20,10 +20,13 @@
import android.view.View;
import android.widget.FrameLayout;
+import com.android.systemui.idle.AmbientLightModeMonitor;
+import com.android.systemui.idle.LightSensorEventsDebounceAlgorithm;
import com.android.systemui.idle.dagger.IdleViewComponent;
import javax.inject.Named;
+import dagger.Binds;
import dagger.Module;
import dagger.Provides;
@@ -44,4 +47,13 @@
FrameLayout view = new FrameLayout(context);
return view;
}
+
+ /**
+ * Provides LightSensorEventsDebounceAlgorithm as an instance to DebounceAlgorithm interface.
+ * @param algorithm the instance of algorithm that is bound to the interface.
+ * @return the interface that is bound to.
+ */
+ @Binds
+ AmbientLightModeMonitor.DebounceAlgorithm ambientLightDebounceAlgorithm(
+ LightSensorEventsDebounceAlgorithm algorithm);
}
diff --git a/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
index ed11db5..f58d628 100644
--- a/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
+++ b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
@@ -81,7 +81,7 @@
val demoFilter = IntentFilter()
demoFilter.addAction(ACTION_DEMO)
context.registerReceiverAsUser(broadcastReceiver, UserHandle.ALL, demoFilter,
- android.Manifest.permission.DUMP, null)
+ android.Manifest.permission.DUMP, null, Context.RECEIVER_EXPORTED)
}
override fun addCallback(listener: DemoMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/idle/AmbientLightModeMonitor.kt b/packages/SystemUI/src/com/android/systemui/idle/AmbientLightModeMonitor.kt
index 8564497..fa00dbb 100644
--- a/packages/SystemUI/src/com/android/systemui/idle/AmbientLightModeMonitor.kt
+++ b/packages/SystemUI/src/com/android/systemui/idle/AmbientLightModeMonitor.kt
@@ -24,17 +24,17 @@
import android.util.Log
import com.android.systemui.util.sensors.AsyncSensorManager
import javax.inject.Inject
-import kotlin.properties.Delegates
/**
* Monitors ambient light signals, applies a debouncing algorithm, and produces the current
- * [AmbientLightMode].
+ * ambient light mode.
*
- * For debouncer behavior, refer to go/titan-light-sensor-debouncer.
- *
+ * @property algorithm the debounce algorithm which transforms light sensor events into an
+ * ambient light mode.
* @property sensorManager the sensor manager used to register sensor event updates.
*/
class AmbientLightModeMonitor @Inject constructor(
+ private val algorithm: DebounceAlgorithm,
private val sensorManager: AsyncSensorManager
) {
companion object {
@@ -47,41 +47,27 @@
}
// Light sensor used to detect ambient lighting conditions.
- private val lightSensor: Sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)
-
- // Registered callback, which gets triggered when the ambient light mode changes.
- private var callback: Callback? = null
+ private val lightSensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)
// Represents all ambient light modes.
@Retention(AnnotationRetention.SOURCE)
@IntDef(AMBIENT_LIGHT_MODE_LIGHT, AMBIENT_LIGHT_MODE_DARK, AMBIENT_LIGHT_MODE_UNDECIDED)
annotation class AmbientLightMode
- // The current ambient light mode.
- @AmbientLightMode private var mode: Int by Delegates.observable(AMBIENT_LIGHT_MODE_UNDECIDED
- ) { _, old, new ->
- if (old != new) {
- callback?.onChange(new)
- }
- }
-
/**
* Start monitoring the current ambient light mode.
*
- * @param callback callback that gets triggered when the ambient light mode changes. It also
- * gets triggered immediately to update the current value when this function is called.
+ * @param callback callback that gets triggered when the ambient light mode changes.
*/
fun start(callback: Callback) {
if (DEBUG) Log.d(TAG, "start monitoring ambient light mode")
- if (this.callback != null) {
- if (DEBUG) Log.w(TAG, "already started")
+ if (lightSensor == null) {
+ if (DEBUG) Log.w(TAG, "light sensor not available")
return
}
- this.callback = callback
- callback.onChange(mode)
-
+ algorithm.start(callback)
sensorManager.registerListener(mSensorEventListener, lightSensor,
SensorManager.SENSOR_DELAY_NORMAL)
}
@@ -92,12 +78,7 @@
fun stop() {
if (DEBUG) Log.d(TAG, "stop monitoring ambient light mode")
- if (callback == null) {
- if (DEBUG) Log.w(TAG, "haven't started")
- return
- }
-
- callback = null
+ algorithm.stop()
sensorManager.unregisterListener(mSensorEventListener)
}
@@ -108,9 +89,7 @@
return
}
- // TODO(b/201657509): add debouncing logic.
- val shouldBeLowLight = event.values[0] < 10
- mode = if (shouldBeLowLight) AMBIENT_LIGHT_MODE_DARK else AMBIENT_LIGHT_MODE_LIGHT
+ algorithm.onUpdateLightSensorEvent(event.values[0])
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
@@ -124,4 +103,14 @@
interface Callback {
fun onChange(@AmbientLightMode mode: Int)
}
+
+ /**
+ * Interface of the algorithm that transforms light sensor events to an ambient light mode.
+ */
+ interface DebounceAlgorithm {
+ // Setting Callback to nullable so mockito can verify without throwing NullPointerException.
+ fun start(callback: Callback?)
+ fun stop()
+ fun onUpdateLightSensorEvent(value: Float)
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/idle/LightSensorEventsDebounceAlgorithm.kt b/packages/SystemUI/src/com/android/systemui/idle/LightSensorEventsDebounceAlgorithm.kt
new file mode 100644
index 0000000..7b06b96
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/idle/LightSensorEventsDebounceAlgorithm.kt
@@ -0,0 +1,284 @@
+/*
+ * 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.systemui.idle
+
+import android.content.res.Resources
+import android.util.Log
+import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.util.concurrency.DelayableExecutor
+import javax.inject.Inject
+
+/**
+ * An algorithm that receives light sensor events, debounces the signals, and transforms into an
+ * ambient light mode: light, dark, or undecided.
+ *
+ * More about the algorithm at go/titan-light-sensor-debouncer.
+ */
+class LightSensorEventsDebounceAlgorithm @Inject constructor(
+ @Main private val executor: DelayableExecutor,
+ @Main resources: Resources
+) : AmbientLightModeMonitor.DebounceAlgorithm {
+ companion object {
+ private const val TAG = "LightDebounceAlgorithm"
+ private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
+ }
+
+ // The ambient mode is considered light mode when the light sensor value increases exceeding
+ // this value.
+ private val lightModeThreshold =
+ resources.getInteger(R.integer.config_ambientLightModeThreshold)
+
+ // The ambient mode is considered dark mode when the light sensor value drops below this
+ // value.
+ private val darkModeThreshold = resources.getInteger(R.integer.config_ambientDarkModeThreshold)
+
+ // Each sample for calculating light mode contains light sensor events collected for this
+ // duration of time in milliseconds.
+ private val lightSamplingSpanMillis =
+ resources.getInteger(R.integer.config_ambientLightModeSamplingSpanMillis)
+
+ // Each sample for calculating dark mode contains light sensor events collected for this
+ // duration of time in milliseconds.
+ private val darkSamplingSpanMillis =
+ resources.getInteger(R.integer.config_ambientDarkModeSamplingSpanMillis)
+
+ // The calculations for light mode is performed at this frequency in milliseconds.
+ private val lightSamplingFrequencyMillis =
+ resources.getInteger(R.integer.config_ambientLightModeSamplingFrequencyMillis)
+
+ // The calculations for dark mode is performed at this frequency in milliseconds.
+ private val darkSamplingFrequencyMillis =
+ resources.getInteger(R.integer.config_ambientDarkModeSamplingFrequencyMillis)
+
+ // Registered callback, which gets triggered when the ambient light mode changes.
+ private var callback: AmbientLightModeMonitor.Callback? = null
+
+ // Queue of bundles used for calculating [isLightMode], ordered from oldest to latest.
+ val bundlesQueueLightMode = ArrayList<ArrayList<Float>>()
+
+ // Queue of bundles used for calculating [isDarkMode], ordered from oldest to latest
+ val bundlesQueueDarkMode = ArrayList<ArrayList<Float>>()
+
+ // The current ambient light mode.
+ @AmbientLightModeMonitor.AmbientLightMode
+ var mode = AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED
+ set(value) {
+ if (field == value) return
+ field = value
+
+ if (DEBUG) Log.d(TAG, "ambient light mode changed to $value")
+
+ callback?.onChange(value)
+ }
+
+ // The latest claim of whether it should be light mode.
+ var isLightMode = false
+ set(value) {
+ if (field == value) return
+ field = value
+
+ if (DEBUG) Log.d(TAG, "isLightMode: $value")
+
+ mode = when {
+ isDarkMode -> AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK
+ value -> AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT
+ else -> AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED
+ }
+ }
+
+ // The latest claim of whether it should be dark mode.
+ var isDarkMode = false
+ set(value) {
+ if (field == value) return
+ field = value
+
+ if (DEBUG) Log.d(TAG, "isDarkMode: $value")
+
+ mode = when {
+ value -> AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK
+ isLightMode -> AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT
+ else -> AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED
+ }
+ }
+
+ // The latest average of the light mode bundle.
+ var bundleAverageLightMode = 0.0
+ set(value) {
+ field = value
+
+ if (DEBUG) Log.d(TAG, "light mode average: $value")
+
+ isLightMode = value > lightModeThreshold
+ }
+
+ // The latest average of the dark mode bundle.
+ var bundleAverageDarkMode = 0.0
+ set(value) {
+ field = value
+
+ if (DEBUG) Log.d(TAG, "dark mode average: $value")
+
+ isDarkMode = value < darkModeThreshold
+ }
+
+ // The latest bundle for calculating light mode claim.
+ var bundleLightMode = ArrayList<Float>()
+ set(value) {
+ field = value
+
+ val average = value.average()
+
+ if (!average.isNaN()) {
+ bundleAverageLightMode = average
+ }
+ }
+
+ // The latest bundle for calculating dark mode claim.
+ var bundleDarkMode = ArrayList<Float>()
+ set(value) {
+ field = value
+
+ val average = value.average()
+
+ if (!average.isNaN()) {
+ bundleAverageDarkMode = average
+ }
+ }
+
+ // The latest light level from light sensor event updates.
+ var lightSensorLevel = 0.0f
+ set(value) {
+ field = value
+
+ bundlesQueueLightMode.forEach { bundle -> bundle.add(value) }
+ bundlesQueueDarkMode.forEach { bundle -> bundle.add(value) }
+ }
+
+ // Creates a new bundle that collects light sensor events for calculating the light mode claim,
+ // and adds it to the end of the queue. It schedules a call to dequeue this bundle after
+ // [LIGHT_SAMPLING_SPAN_MILLIS]. Once started, it also repeatedly calls itself at
+ // [LIGHT_SAMPLING_FREQUENCY_MILLIS].
+ val enqueueLightModeBundle: Runnable = object : Runnable {
+ override fun run() {
+ if (DEBUG) Log.d(TAG, "enqueueing a light mode bundle")
+
+ bundlesQueueLightMode.add(ArrayList())
+
+ executor.executeDelayed(dequeueLightModeBundle, lightSamplingSpanMillis.toLong())
+ executor.executeDelayed(this, lightSamplingFrequencyMillis.toLong())
+ }
+ }
+
+ // Creates a new bundle that collects light sensor events for calculating the dark mode claim,
+ // and adds it to the end of the queue. It schedules a call to dequeue this bundle after
+ // [DARK_SAMPLING_SPAN_MILLIS]. Once started, it also repeatedly calls itself at
+ // [DARK_SAMPLING_FREQUENCY_MILLIS].
+ val enqueueDarkModeBundle: Runnable = object : Runnable {
+ override fun run() {
+ if (DEBUG) Log.d(TAG, "enqueueing a dark mode bundle")
+
+ bundlesQueueDarkMode.add(ArrayList())
+
+ executor.executeDelayed(dequeueDarkModeBundle, darkSamplingSpanMillis.toLong())
+ executor.executeDelayed(this, darkSamplingFrequencyMillis.toLong())
+ }
+ }
+
+ // Collects the oldest bundle from the light mode bundles queue, and as a result triggering a
+ // calculation of the light mode claim.
+ val dequeueLightModeBundle: Runnable = object : Runnable {
+ override fun run() {
+ if (bundlesQueueLightMode.isEmpty()) return
+
+ bundleLightMode = bundlesQueueLightMode.removeAt(0)
+
+ if (DEBUG) Log.d(TAG, "dequeued a light mode bundle of size ${bundleLightMode.size}")
+ }
+ }
+
+ // Collects the oldest bundle from the dark mode bundles queue, and as a result triggering a
+ // calculation of the dark mode claim.
+ val dequeueDarkModeBundle: Runnable = object : Runnable {
+ override fun run() {
+ if (bundlesQueueDarkMode.isEmpty()) return
+
+ bundleDarkMode = bundlesQueueDarkMode.removeAt(0)
+
+ if (DEBUG) Log.d(TAG, "dequeued a dark mode bundle of size ${bundleDarkMode.size}")
+ }
+ }
+
+ /**
+ * Start the algorithm.
+ *
+ * @param callback callback that gets triggered when the ambient light mode changes.
+ */
+ override fun start(callback: AmbientLightModeMonitor.Callback?) {
+ if (DEBUG) Log.d(TAG, "start algorithm")
+
+ if (callback == null) {
+ if (DEBUG) Log.w(TAG, "callback is null")
+ return
+ }
+
+ if (this.callback != null) {
+ if (DEBUG) Log.w(TAG, "already started")
+ return
+ }
+
+ this.callback = callback
+
+ executor.execute(enqueueLightModeBundle)
+ executor.execute(enqueueDarkModeBundle)
+ }
+
+ /**
+ * Stop the algorithm.
+ */
+ override fun stop() {
+ if (DEBUG) Log.d(TAG, "stop algorithm")
+
+ if (callback == null) {
+ if (DEBUG) Log.w(TAG, "haven't started")
+ return
+ }
+
+ callback = null
+
+ // Resets bundle queues.
+ bundlesQueueLightMode.clear()
+ bundlesQueueDarkMode.clear()
+
+ // Resets ambient light mode.
+ mode = AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED
+ }
+
+ /**
+ * Update the light sensor event value.
+ *
+ * @param value light sensor update value.
+ */
+ override fun onUpdateLightSensorEvent(value: Float) {
+ if (callback == null) {
+ if (DEBUG) Log.w(TAG, "ignore light sensor event because algorithm not started")
+ return
+ }
+
+ lightSensorLevel = value
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 8c66ba3..4e1e1cd 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -749,7 +749,7 @@
filter.addAction(ACTION_AUTO_SAVER_NO_THANKS);
filter.addAction(ACTION_DISMISS_AUTO_SAVER_SUGGESTION);
mContext.registerReceiverAsUser(this, UserHandle.ALL, filter,
- android.Manifest.permission.DEVICE_POWER, mHandler);
+ android.Manifest.permission.DEVICE_POWER, mHandler, Context.RECEIVER_EXPORTED);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index a42b34c..ba6e98e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -78,6 +78,7 @@
private ImageView mTransitionView;
private ImageView mEnterTransitionView;
private View mSave;
+ private View mCancel;
private View mEdit;
private View mShare;
private CropView mCropView;
@@ -119,15 +120,15 @@
mSave = requireViewById(R.id.save);
mEdit = requireViewById(R.id.edit);
mShare = requireViewById(R.id.share);
+ mCancel = requireViewById(R.id.cancel);
mCropView = requireViewById(R.id.crop_view);
mMagnifierView = requireViewById(R.id.magnifier);
mCropView.setCropInteractionListener(mMagnifierView);
mTransitionView = requireViewById(R.id.transition);
mEnterTransitionView = requireViewById(R.id.enter_transition);
- requireViewById(R.id.cancel).setOnClickListener(v -> finishAndRemoveTask());
-
mSave.setOnClickListener(this::onClicked);
+ mCancel.setOnClickListener(this::onClicked);
mEdit.setOnClickListener(this::onClicked);
mShare.setOnClickListener(this::onClicked);
@@ -353,6 +354,7 @@
v.setPressed(true);
setButtonsEnabled(false);
if (id == R.id.save) {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_SAVED);
startExport(PendingAction.SAVE);
} else if (id == R.id.edit) {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_EDIT);
@@ -360,6 +362,9 @@
} else if (id == R.id.share) {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_SHARE);
startExport(PendingAction.SHARE);
+ } else if (id == R.id.cancel) {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_EXIT);
+ finishAndRemoveTask();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java
index 169b28c..d49ff93 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java
@@ -83,7 +83,11 @@
@UiEvent(doc = "Long screenshot editor activity loaded a previously saved screenshot")
SCREENSHOT_LONG_SCREENSHOT_ACTIVITY_CACHED_IMAGE_LOADED(890),
@UiEvent(doc = "Long screenshot editor activity finished")
- SCREENSHOT_LONG_SCREENSHOT_ACTIVITY_FINISHED(891);
+ SCREENSHOT_LONG_SCREENSHOT_ACTIVITY_FINISHED(891),
+ @UiEvent(doc = "User has saved a long screenshot to a file")
+ SCREENSHOT_LONG_SCREENSHOT_SAVED(910),
+ @UiEvent(doc = "User has discarded the result of a long screenshot")
+ SCREENSHOT_LONG_SCREENSHOT_EXIT(911);
private final int mId;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index 277b4ac..dfdc548 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -523,7 +523,9 @@
}
}
- private void onEndLifetimeExtension(NotifLifetimeExtender extender, NotificationEntry entry) {
+ private void onEndLifetimeExtension(
+ @NonNull NotifLifetimeExtender extender,
+ @NonNull NotificationEntry entry) {
Assert.isMainThread();
if (!mAttached) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinator.kt
new file mode 100644
index 0000000..8948969
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinator.kt
@@ -0,0 +1,126 @@
+/*
+ * 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.systemui.statusbar.notification.collection.coordinator
+
+import android.util.ArraySet
+import com.android.systemui.Dumpable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender.OnEndLifetimeExtensionCallback
+import com.android.systemui.statusbar.notification.row.NotificationGuts
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager
+import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewListener
+import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import javax.inject.Inject
+
+private const val TAG = "GutsCoordinator"
+
+/**
+ * Coordinates the guts displayed by the [NotificationGutsManager] with the pipeline.
+ * Specifically, this just adds the lifetime extension necessary to keep guts from disappearing.
+ */
+@SysUISingleton
+class GutsCoordinator @Inject constructor(
+ private val notifGutsViewManager: NotifGutsViewManager,
+ private val logger: GutsCoordinatorLogger,
+ dumpManager: DumpManager
+) : Coordinator, Dumpable {
+
+ /** Keys of any Notifications for which we've been told the guts are open */
+ private val notifsWithOpenGuts = ArraySet<String>()
+
+ /** Keys of any Notifications we've extended the lifetime for, based on guts */
+ private val notifsExtendingLifetime = ArraySet<String>()
+
+ /** Callback for ending lifetime extension */
+ private var onEndLifetimeExtensionCallback: OnEndLifetimeExtensionCallback? = null
+
+ init {
+ dumpManager.registerDumpable(TAG, this)
+ }
+
+ override fun attach(pipeline: NotifPipeline) {
+ notifGutsViewManager.setGutsListener(mGutsListener)
+ pipeline.addNotificationLifetimeExtender(mLifetimeExtender)
+ }
+
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
+ pw.println(" notifsWithOpenGuts: ${notifsWithOpenGuts.size}")
+ for (key in notifsWithOpenGuts) {
+ pw.println(" * $key")
+ }
+ pw.println(" notifsExtendingLifetime: ${notifsExtendingLifetime.size}")
+ for (key in notifsExtendingLifetime) {
+ pw.println(" * $key")
+ }
+ pw.println(" onEndLifetimeExtensionCallback: $onEndLifetimeExtensionCallback")
+ }
+
+ private val mLifetimeExtender: NotifLifetimeExtender = object : NotifLifetimeExtender {
+ override fun getName(): String {
+ return TAG
+ }
+
+ override fun setCallback(callback: OnEndLifetimeExtensionCallback) {
+ onEndLifetimeExtensionCallback = callback
+ }
+
+ override fun shouldExtendLifetime(entry: NotificationEntry, reason: Int): Boolean {
+ val isShowingGuts = isCurrentlyShowingGuts(entry)
+ if (isShowingGuts) {
+ notifsExtendingLifetime.add(entry.key)
+ }
+ return isShowingGuts
+ }
+
+ override fun cancelLifetimeExtension(entry: NotificationEntry) {
+ notifsExtendingLifetime.remove(entry.key)
+ }
+ }
+
+ private val mGutsListener: NotifGutsViewListener = object : NotifGutsViewListener {
+ override fun onGutsOpen(entry: NotificationEntry, guts: NotificationGuts) {
+ logger.logGutsOpened(entry.key, guts)
+ if (guts.isLeavebehind) {
+ // leave-behind guts should not extend the lifetime of the notification
+ closeGutsAndEndLifetimeExtension(entry)
+ } else {
+ notifsWithOpenGuts.add(entry.key)
+ }
+ }
+
+ override fun onGutsClose(entry: NotificationEntry) {
+ logger.logGutsClosed(entry.key)
+ closeGutsAndEndLifetimeExtension(entry)
+ }
+ }
+
+ private fun isCurrentlyShowingGuts(entry: ListEntry) =
+ notifsWithOpenGuts.contains(entry.key)
+
+ private fun closeGutsAndEndLifetimeExtension(entry: NotificationEntry) {
+ notifsWithOpenGuts.remove(entry.key)
+ if (notifsExtendingLifetime.remove(entry.key)) {
+ onEndLifetimeExtensionCallback?.onEndLifetimeExtension(mLifetimeExtender, entry)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorLogger.kt
new file mode 100644
index 0000000..bac5223
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorLogger.kt
@@ -0,0 +1,32 @@
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.statusbar.notification.row.NotificationGuts
+import javax.inject.Inject
+
+private const val TAG = "GutsCoordinator"
+
+class GutsCoordinatorLogger @Inject constructor(
+ @NotificationLog private val buffer: LogBuffer
+) {
+
+ fun logGutsOpened(key: String, guts: NotificationGuts) {
+ buffer.log(TAG, LogLevel.DEBUG, {
+ str1 = key
+ str2 = guts::class.simpleName
+ bool1 = guts.isLeavebehind
+ }, {
+ "Guts of type $str2 (leave behind: $bool1) opened for class $str1"
+ })
+ }
+
+ fun logGutsClosed(key: String) {
+ buffer.log(TAG, LogLevel.DEBUG, {
+ str1 = key
+ }, {
+ "Guts closed for class $str1"
+ })
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
index 4d36251..8c8a8a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
@@ -19,7 +19,8 @@
import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
import static com.android.systemui.statusbar.notification.interruption.HeadsUpController.alertAgain;
-import android.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -164,17 +165,17 @@
private final NotifLifetimeExtender mLifetimeExtender = new NotifLifetimeExtender() {
@Override
- public String getName() {
+ public @NonNull String getName() {
return TAG;
}
@Override
- public void setCallback(OnEndLifetimeExtensionCallback callback) {
+ public void setCallback(@NonNull OnEndLifetimeExtensionCallback callback) {
mEndLifetimeExtension = callback;
}
@Override
- public boolean shouldExtendLifetime(NotificationEntry entry, int reason) {
+ public boolean shouldExtendLifetime(@NonNull NotificationEntry entry, int reason) {
boolean isShowingHun = isCurrentlyShowingHun(entry);
if (isShowingHun) {
mNotifExtendingLifetime = entry;
@@ -183,7 +184,7 @@
}
@Override
- public void cancelLifetimeExtension(NotificationEntry entry) {
+ public void cancelLifetimeExtension(@NonNull NotificationEntry entry) {
if (Objects.equals(mNotifExtendingLifetime, entry)) {
mNotifExtendingLifetime = null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
index 47bc444..18f3b45 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
@@ -57,6 +57,7 @@
DeviceProvisionedCoordinator deviceProvisionedCoordinator,
BubbleCoordinator bubbleCoordinator,
HeadsUpCoordinator headsUpCoordinator,
+ GutsCoordinator gutsCoordinator,
ConversationCoordinator conversationCoordinator,
PreparationCoordinator preparationCoordinator,
MediaCoordinator mediaCoordinator,
@@ -83,6 +84,7 @@
if (featureFlags.isNewNotifPipelineRenderingEnabled()) {
mCoordinators.add(headsUpCoordinator);
+ mCoordinators.add(gutsCoordinator);
mCoordinators.add(preparationCoordinator);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifLifetimeExtender.java
index f8fe067..2fe3bd6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifLifetimeExtender.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifLifetimeExtender.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.collection.notifcollection;
+import androidx.annotation.NonNull;
+
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -26,14 +28,14 @@
*/
public interface NotifLifetimeExtender {
/** Name to associate with this extender (for the purposes of debugging) */
- String getName();
+ @NonNull String getName();
/**
* Called on the extender immediately after it has been registered. The extender should hang on
* to this callback and execute it whenever it no longer needs to extend the lifetime of a
* notification.
*/
- void setCallback(OnEndLifetimeExtensionCallback callback);
+ void setCallback(@NonNull OnEndLifetimeExtensionCallback callback);
/**
* Called by the NotifCollection whenever a notification has been retracted (by the app) or
@@ -43,7 +45,7 @@
* called on all lifetime extenders even if earlier ones return true (in other words, multiple
* lifetime extenders can be extending a notification at the same time).
*/
- boolean shouldExtendLifetime(NotificationEntry entry, @CancellationReason int reason);
+ boolean shouldExtendLifetime(@NonNull NotificationEntry entry, @CancellationReason int reason);
/**
* Called by the NotifCollection to inform a lifetime extender that its extension of a notif
@@ -51,7 +53,7 @@
* lifetime extension). The extender should clean up any references it has to the notif in
* question.
*/
- void cancelLifetimeExtension(NotificationEntry entry);
+ void cancelLifetimeExtension(@NonNull NotificationEntry entry);
/** Callback for notifying the NotifCollection that a lifetime extension has expired.*/
interface OnEndLifetimeExtensionCallback {
@@ -59,6 +61,8 @@
* Stop extending the lifetime of `entry` with `extender` and then immediately re-evaluates
* whether to continue lifetime extending this notification or to remove it.
*/
- void onEndLifetimeExtension(NotifLifetimeExtender extender, NotificationEntry entry);
+ void onEndLifetimeExtension(
+ @NonNull NotifLifetimeExtender extender,
+ @NonNull NotificationEntry entry);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewListener.kt
new file mode 100644
index 0000000..129f6b1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewListener.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.systemui.statusbar.notification.collection.render
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.row.NotificationGuts
+
+/**
+ * Interface for listening to guts open and close events.
+ */
+interface NotifGutsViewListener {
+ /** A notification's guts are being opened */
+ fun onGutsOpen(entry: NotificationEntry, guts: NotificationGuts)
+
+ /** A notification's guts are being closed */
+ fun onGutsClose(entry: NotificationEntry)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewManager.kt
new file mode 100644
index 0000000..0260f89
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewManager.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.systemui.statusbar.notification.collection.render
+
+/** A type which provides open and close guts events to a single listener */
+interface NotifGutsViewManager {
+ /**
+ * @param listener the object that will listen to open and close guts events
+ */
+ fun setGutsListener(listener: NotifGutsViewListener?)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 94f5c44..dfa1f5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -58,6 +58,7 @@
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl;
+import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.init.NotificationsControllerImpl;
import com.android.systemui.statusbar.notification.init.NotificationsControllerStub;
@@ -169,6 +170,14 @@
dumpManager);
}
+ /** Provides an instance of {@link NotifGutsViewManager} */
+ @SysUISingleton
+ @Provides
+ static NotifGutsViewManager provideNotifGutsViewManager(
+ NotificationGutsManager notificationGutsManager) {
+ return notificationGutsManager;
+ }
+
/** Provides an instance of {@link VisualStabilityManager} */
@SysUISingleton
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 7eec95a..8e02d9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -65,6 +65,8 @@
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewListener;
+import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
@@ -83,7 +85,8 @@
* Handles various NotificationGuts related tasks, such as binding guts to a row, opening and
* closing guts, and keeping track of the currently exposed notification guts.
*/
-public class NotificationGutsManager implements Dumpable, NotificationLifetimeExtender {
+public class NotificationGutsManager implements Dumpable, NotificationLifetimeExtender,
+ NotifGutsViewManager {
private static final String TAG = "NotificationGutsManager";
// Must match constant in Settings. Used to highlight preferences when linking to Settings.
@@ -123,7 +126,6 @@
private final Optional<BubblesManager> mBubblesManagerOptional;
private Runnable mOpenRunnable;
private final INotificationManager mNotificationManager;
- private final NotificationEntryManager mNotificationEntryManager;
private final PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
private final LauncherApps mLauncherApps;
private final ShortcutManager mShortcutManager;
@@ -131,6 +133,7 @@
private final UiEventLogger mUiEventLogger;
private final ShadeController mShadeController;
private final AppWidgetManager mAppWidgetManager;
+ private NotifGutsViewListener mGutsListener;
/**
* Injected constructor. See {@link NotificationsModule}.
@@ -161,7 +164,6 @@
mAccessibilityManager = accessibilityManager;
mHighPriorityProvider = highPriorityProvider;
mNotificationManager = notificationManager;
- mNotificationEntryManager = notificationEntryManager;
mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;
mLauncherApps = launcherApps;
mShortcutManager = shortcutManager;
@@ -258,10 +260,10 @@
@VisibleForTesting
protected boolean bindGuts(final ExpandableNotificationRow row,
NotificationMenuRowPlugin.MenuItem item) {
- StatusBarNotification sbn = row.getEntry().getSbn();
+ NotificationEntry entry = row.getEntry();
row.setGutsView(item);
- row.setTag(sbn.getPackageName());
+ row.setTag(entry.getSbn().getPackageName());
row.getGuts().setClosedListener((NotificationGuts g) -> {
row.onGutsClosed();
if (!g.willBeRemoved() && !row.isRemoved()) {
@@ -272,7 +274,10 @@
mNotificationGutsExposed = null;
mGutsMenuItem = null;
}
- String key = sbn.getKey();
+ if (mGutsListener != null) {
+ mGutsListener.onGutsClose(entry);
+ }
+ String key = entry.getKey();
if (key.equals(mKeyToRemoveOnGutsClosed)) {
mKeyToRemoveOnGutsClosed = null;
if (mNotificationLifetimeFinishedCallback != null) {
@@ -650,6 +655,10 @@
needsFalsingProtection,
row::onGutsOpened);
+ if (mGutsListener != null) {
+ mGutsListener.onGutsOpen(row.getEntry(), guts);
+ }
+
row.closeRemoteInput();
mListContainer.onHeightChanged(row, true /* needsAnimation */);
mGutsMenuItem = menuItem;
@@ -695,10 +704,17 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("NotificationGutsManager state:");
- pw.print(" mKeyToRemoveOnGutsClosed: ");
+ pw.print(" mKeyToRemoveOnGutsClosed (legacy): ");
pw.println(mKeyToRemoveOnGutsClosed);
}
+ /**
+ * @param gutsListener the listener for open and close guts events
+ */
+ public void setGutsListener(NotifGutsViewListener gutsListener) {
+ mGutsListener = gutsListener;
+ }
+
public interface OnSettingsClickListener {
public void onSettingsClick(String key);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index e27f458..de21e73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -18,25 +18,28 @@
import android.graphics.Point
import android.view.View
import android.view.ViewGroup
+import android.view.ViewTreeObserver
import com.android.systemui.R
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.unfold.UNFOLD_STATUS_BAR
+import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import com.android.systemui.util.ViewController
+import javax.inject.Inject
+import javax.inject.Named
+import dagger.Lazy
/** Controller for [PhoneStatusBarView]. */
-class PhoneStatusBarViewController(
+class PhoneStatusBarViewController private constructor(
view: PhoneStatusBarView,
- statusBarMoveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
+ @Named(UNFOLD_STATUS_BAR) private val progressProvider: ScopedUnfoldTransitionProgressProvider?,
+ private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
touchEventHandler: PhoneStatusBarView.TouchEventHandler,
) : ViewController<PhoneStatusBarView>(view) {
- override fun onViewAttached() {}
- override fun onViewDetached() {}
-
- init {
- mView.setTouchEventHandler(touchEventHandler)
-
- statusBarMoveFromCenterAnimationController?.let { animationController ->
+ override fun onViewAttached() {
+ moveFromCenterAnimationController?.let { animationController ->
val statusBarLeftSide: View = mView.findViewById(R.id.status_bar_left_side)
val systemIconArea: ViewGroup = mView.findViewById(R.id.system_icon_area)
@@ -46,15 +49,33 @@
systemIconArea
)
- animationController.init(viewsToAnimate, viewCenterProvider)
+ mView.viewTreeObserver.addOnPreDrawListener(object :
+ ViewTreeObserver.OnPreDrawListener {
+ override fun onPreDraw(): Boolean {
+ animationController.onViewsReady(viewsToAnimate, viewCenterProvider)
+ mView.viewTreeObserver.removeOnPreDrawListener(this)
+ return true
+ }
+ })
mView.addOnLayoutChangeListener { _, left, _, right, _, oldLeft, _, oldRight, _ ->
val widthChanged = right - left != oldRight - oldLeft
if (widthChanged) {
- statusBarMoveFromCenterAnimationController.onStatusBarWidthChanged()
+ moveFromCenterAnimationController.onStatusBarWidthChanged()
}
}
}
+
+ progressProvider?.setReadyToHandleTransition(true)
+ }
+
+ override fun onViewDetached() {
+ progressProvider?.setReadyToHandleTransition(false)
+ moveFromCenterAnimationController?.onViewDetached()
+ }
+
+ init {
+ mView.setTouchEventHandler(touchEventHandler)
}
fun setImportantForAccessibility(mode: Int) {
@@ -92,4 +113,23 @@
outPoint.y = viewY + view.height / 2
}
}
+
+ class Factory @Inject constructor(
+ @Named(UNFOLD_STATUS_BAR)
+ private val progressProvider: Lazy<ScopedUnfoldTransitionProgressProvider>,
+ private val moveFromCenterController: Lazy<StatusBarMoveFromCenterAnimationController>,
+ private val unfoldConfig: UnfoldTransitionConfig,
+ ) {
+ fun create(
+ view: PhoneStatusBarView,
+ touchEventHandler: PhoneStatusBarView.TouchEventHandler
+ ): PhoneStatusBarViewController {
+ return PhoneStatusBarViewController(
+ view,
+ if (unfoldConfig.isEnabled) progressProvider.get() else null,
+ if (unfoldConfig.isEnabled) moveFromCenterController.get() else null,
+ touchEventHandler
+ )
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index f7890c9..0e75a45 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -233,6 +233,7 @@
import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation;
import com.android.systemui.unfold.UnfoldTransitionWallpaperController;
import com.android.systemui.unfold.config.UnfoldTransitionConfig;
+import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
import com.android.systemui.util.WallpaperController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.MessageRouter;
@@ -525,6 +526,7 @@
private QSPanelController mQSPanelController;
private final OperatorNameViewController.Factory mOperatorNameViewControllerFactory;
+ private final PhoneStatusBarViewController.Factory mPhoneStatusBarViewControllerFactory;
KeyguardIndicationController mKeyguardIndicationController;
private View mReportRejectedTouch;
@@ -543,8 +545,8 @@
private final FeatureFlags mFeatureFlags;
private final UnfoldTransitionConfig mUnfoldTransitionConfig;
private final Lazy<UnfoldLightRevealOverlayAnimation> mUnfoldLightRevealOverlayAnimation;
+ private final Lazy<NaturalRotationUnfoldProgressProvider> mNaturalUnfoldProgressProvider;
private final Lazy<UnfoldTransitionWallpaperController> mUnfoldWallpaperController;
- private final Lazy<StatusBarMoveFromCenterAnimationController> mMoveFromCenterAnimation;
private final WallpaperController mWallpaperController;
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private final MessageRouter mMessageRouter;
@@ -772,6 +774,7 @@
ExtensionController extensionController,
UserInfoControllerImpl userInfoControllerImpl,
OperatorNameViewController.Factory operatorNameViewControllerFactory,
+ PhoneStatusBarViewController.Factory phoneStatusBarViewControllerFactory,
PhoneStatusBarPolicy phoneStatusBarPolicy,
KeyguardIndicationController keyguardIndicationController,
DemoModeController demoModeController,
@@ -782,7 +785,7 @@
UnfoldTransitionConfig unfoldTransitionConfig,
Lazy<UnfoldLightRevealOverlayAnimation> unfoldLightRevealOverlayAnimation,
Lazy<UnfoldTransitionWallpaperController> unfoldTransitionWallpaperController,
- Lazy<StatusBarMoveFromCenterAnimationController> statusBarUnfoldAnimationController,
+ Lazy<NaturalRotationUnfoldProgressProvider> naturalRotationUnfoldProgressProvider,
WallpaperController wallpaperController,
OngoingCallController ongoingCallController,
SystemStatusAnimationScheduler animationScheduler,
@@ -812,6 +815,7 @@
mKeyguardStateController = keyguardStateController;
mHeadsUpManager = headsUpManagerPhone;
mOperatorNameViewControllerFactory = operatorNameViewControllerFactory;
+ mPhoneStatusBarViewControllerFactory = phoneStatusBarViewControllerFactory;
mKeyguardIndicationController = keyguardIndicationController;
mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
mDynamicPrivacyController = dynamicPrivacyController;
@@ -879,9 +883,9 @@
mBrightnessSliderFactory = brightnessSliderFactory;
mUnfoldTransitionConfig = unfoldTransitionConfig;
mUnfoldLightRevealOverlayAnimation = unfoldLightRevealOverlayAnimation;
+ mNaturalUnfoldProgressProvider = naturalRotationUnfoldProgressProvider;
mUnfoldWallpaperController = unfoldTransitionWallpaperController;
mWallpaperController = wallpaperController;
- mMoveFromCenterAnimation = statusBarUnfoldAnimationController;
mOngoingCallController = ongoingCallController;
mAnimationScheduler = animationScheduler;
mStatusBarLocationPublisher = locationPublisher;
@@ -1077,6 +1081,7 @@
if (mUnfoldTransitionConfig.isEnabled()) {
mUnfoldLightRevealOverlayAnimation.get().init();
mUnfoldWallpaperController.get().init();
+ mNaturalUnfoldProgressProvider.get().init();
}
mPluginManager.addPluginListener(
@@ -1178,16 +1183,9 @@
mNotificationPanelViewController.setBar(mStatusBarView);
- StatusBarMoveFromCenterAnimationController moveFromCenterAnimation = null;
- if (mUnfoldTransitionConfig.isEnabled()) {
- moveFromCenterAnimation = mMoveFromCenterAnimation.get();
- }
- mPhoneStatusBarViewController =
- new PhoneStatusBarViewController(
- mStatusBarView,
- moveFromCenterAnimation,
- mNotificationPanelViewController.getStatusBarTouchEventHandler()
- );
+ mPhoneStatusBarViewController = mPhoneStatusBarViewControllerFactory
+ .create(mStatusBarView, mNotificationPanelViewController
+ .getStatusBarTouchEventHandler());
mPhoneStatusBarViewController.init();
mBatteryMeterViewController = new BatteryMeterViewController(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt
index 8af03aa..8ef186c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt
@@ -20,43 +20,54 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator.ViewCenterProvider
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.unfold.UNFOLD_STATUS_BAR
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import javax.inject.Inject
+import javax.inject.Named
@SysUISingleton
class StatusBarMoveFromCenterAnimationController @Inject constructor(
- private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
- private val windowManager: WindowManager
+ @Named(UNFOLD_STATUS_BAR) private val progressProvider: ScopedUnfoldTransitionProgressProvider,
+ private val windowManager: WindowManager,
) {
- private lateinit var moveFromCenterAnimator: UnfoldMoveFromCenterAnimator
+ private val transitionListener = TransitionListener()
+ private var moveFromCenterAnimator: UnfoldMoveFromCenterAnimator? = null
- fun init(viewsToAnimate: Array<View>, viewCenterProvider: ViewCenterProvider) {
+ fun onViewsReady(viewsToAnimate: Array<View>, viewCenterProvider: ViewCenterProvider) {
moveFromCenterAnimator = UnfoldMoveFromCenterAnimator(windowManager,
viewCenterProvider = viewCenterProvider)
- unfoldTransitionProgressProvider.addCallback(object : TransitionProgressListener {
- override fun onTransitionStarted() {
- moveFromCenterAnimator.updateDisplayProperties()
+ moveFromCenterAnimator?.updateDisplayProperties()
- viewsToAnimate.forEach {
- moveFromCenterAnimator.registerViewForAnimation(it)
- }
- }
+ viewsToAnimate.forEach {
+ moveFromCenterAnimator?.registerViewForAnimation(it)
+ }
- override fun onTransitionFinished() {
- moveFromCenterAnimator.onTransitionFinished()
- moveFromCenterAnimator.clearRegisteredViews()
- }
+ progressProvider.addCallback(transitionListener)
+ }
- override fun onTransitionProgress(progress: Float) {
- moveFromCenterAnimator.onTransitionProgress(progress)
- }
- })
+ fun onViewDetached() {
+ progressProvider.removeCallback(transitionListener)
+ moveFromCenterAnimator?.clearRegisteredViews()
+ moveFromCenterAnimator = null
}
fun onStatusBarWidthChanged() {
- moveFromCenterAnimator.updateViewPositions()
+ moveFromCenterAnimator?.updateDisplayProperties()
+ moveFromCenterAnimator?.updateViewPositions()
+ }
+
+ private inner class TransitionListener : TransitionProgressListener {
+ override fun onTransitionProgress(progress: Float) {
+ moveFromCenterAnimator?.onTransitionProgress(progress)
+ }
+
+ override fun onTransitionFinished() {
+ // Reset translations when transition is stopped/cancelled
+ // (e.g. the transition could be cancelled mid-way when rotating the screen)
+ moveFromCenterAnimator?.onTransitionProgress(1f)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index fdc0ec5..e2332e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -145,22 +145,24 @@
.setDuration(duration.toLong())
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.alpha(1f)
- .withEndAction {
- aodUiAnimationPlaying = false
+ .setListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ aodUiAnimationPlaying = false
- // Lock the keyguard if it was waiting for the screen off animation to end.
- keyguardViewMediatorLazy.get().maybeHandlePendingLock()
+ // Lock the keyguard if it was waiting for the screen off animation to end.
+ keyguardViewMediatorLazy.get().maybeHandlePendingLock()
- // Tell the StatusBar to become keyguard for real - we waited on that since it
- // is slow and would have caused the animation to jank.
- statusBar.updateIsKeyguard()
+ // Tell the StatusBar to become keyguard for real - we waited on that since
+ // it is slow and would have caused the animation to jank.
+ statusBar.updateIsKeyguard()
- // Run the callback given to us by the KeyguardVisibilityHelper.
- after.run()
+ // Run the callback given to us by the KeyguardVisibilityHelper.
+ after.run()
- // Done going to sleep, reset this flag.
- decidedToAnimateGoingToSleep = null
- }
+ // Done going to sleep, reset this flag.
+ decidedToAnimateGoingToSleep = null
+ }
+ })
.start()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 5689707..c452a48 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -88,6 +88,7 @@
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
+import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -111,6 +112,7 @@
import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation;
import com.android.systemui.unfold.UnfoldTransitionWallpaperController;
import com.android.systemui.unfold.config.UnfoldTransitionConfig;
+import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
import com.android.systemui.util.WallpaperController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.MessageRouter;
@@ -211,6 +213,7 @@
ExtensionController extensionController,
UserInfoControllerImpl userInfoControllerImpl,
OperatorNameViewController.Factory operatorNameViewControllerFactory,
+ PhoneStatusBarViewController.Factory phoneStatusBarViewControllerFactory,
PhoneStatusBarPolicy phoneStatusBarPolicy,
KeyguardIndicationController keyguardIndicationController,
DemoModeController demoModeController,
@@ -220,6 +223,7 @@
BrightnessSlider.Factory brightnessSliderFactory,
UnfoldTransitionConfig unfoldTransitionConfig,
Lazy<UnfoldLightRevealOverlayAnimation> unfoldLightRevealOverlayAnimation,
+ Lazy<NaturalRotationUnfoldProgressProvider> naturalRotationUnfoldProgressProvider,
Lazy<UnfoldTransitionWallpaperController> unfoldTransitionWallpaperController,
Lazy<StatusBarMoveFromCenterAnimationController> statusBarMoveFromCenterAnimation,
WallpaperController wallpaperController,
@@ -311,6 +315,7 @@
extensionController,
userInfoControllerImpl,
operatorNameViewControllerFactory,
+ phoneStatusBarViewControllerFactory,
phoneStatusBarPolicy,
keyguardIndicationController,
demoModeController,
@@ -321,7 +326,7 @@
unfoldTransitionConfig,
unfoldLightRevealOverlayAnimation,
unfoldTransitionWallpaperController,
- statusBarMoveFromCenterAnimation,
+ naturalRotationUnfoldProgressProvider,
wallpaperController,
ongoingCallController,
animationScheduler,
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
index b23aa20..7e4ec67 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -20,15 +20,19 @@
import android.hardware.SensorManager
import android.hardware.devicestate.DeviceStateManager
import android.os.Handler
+import android.view.IWindowManager
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.LifecycleScreenStatusProvider
import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
+import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import com.android.wm.shell.unfold.ShellUnfoldProgressProvider
import dagger.Lazy
import dagger.Module
import dagger.Provides
import java.util.Optional
import java.util.concurrent.Executor
+import javax.inject.Named
import javax.inject.Singleton
@Module
@@ -62,6 +66,27 @@
@Provides
@Singleton
+ fun provideNaturalRotationProgressProvider(
+ context: Context,
+ windowManager: IWindowManager,
+ unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider
+ ): NaturalRotationUnfoldProgressProvider =
+ NaturalRotationUnfoldProgressProvider(
+ context,
+ windowManager,
+ unfoldTransitionProgressProvider
+ )
+
+ @Provides
+ @Named(UNFOLD_STATUS_BAR)
+ @Singleton
+ fun provideStatusBarScopedTransitionProvider(
+ source: NaturalRotationUnfoldProgressProvider
+ ): ScopedUnfoldTransitionProgressProvider =
+ ScopedUnfoldTransitionProgressProvider(source)
+
+ @Provides
+ @Singleton
fun provideShellProgressProvider(
config: UnfoldTransitionConfig,
provider: Lazy<UnfoldTransitionProgressProvider>
@@ -72,3 +97,5 @@
Optional.empty()
}
}
+
+const val UNFOLD_STATUS_BAR = "unfold_status_bar"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
index da4ccd0..c420a6d 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
@@ -112,6 +112,7 @@
mOtherProfileIntent.putParcelableArrayListExtra(EXTRA_RESOLVE_INFOS,
rListOtherProfile);
} else {
+ mOtherProfileIntent = new Intent();
mOtherProfileIntent.setComponent(ComponentName.unflattenFromString(
this.getResources().getString(
com.android.internal.R.string.config_usbConfirmActivity)));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/idle/AmbientLightModeMonitorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/idle/AmbientLightModeMonitorTest.kt
index 9bd5bc7..98b9252 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/idle/AmbientLightModeMonitorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/idle/AmbientLightModeMonitorTest.kt
@@ -17,7 +17,6 @@
package com.android.systemui.idle
import android.hardware.Sensor
-import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
@@ -29,11 +28,11 @@
import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.Mockito.verify
-import org.mockito.Mockito.reset
import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.any
+import org.mockito.Mockito.eq
+import org.mockito.Mockito.never
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@@ -42,6 +41,7 @@
class AmbientLightModeMonitorTest : SysuiTestCase() {
@Mock private lateinit var sensorManager: AsyncSensorManager
@Mock private lateinit var sensor: Sensor
+ @Mock private lateinit var algorithm: AmbientLightModeMonitor.DebounceAlgorithm
private lateinit var ambientLightModeMonitor: AmbientLightModeMonitor
@@ -50,100 +50,56 @@
MockitoAnnotations.initMocks(this)
`when`(sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)).thenReturn(sensor)
- ambientLightModeMonitor = AmbientLightModeMonitor(sensorManager)
+
+ ambientLightModeMonitor = AmbientLightModeMonitor(algorithm, sensorManager)
}
@Test
- fun shouldTriggerCallbackImmediatelyOnStart() {
+ fun shouldRegisterSensorEventListenerOnStart() {
val callback = mock(AmbientLightModeMonitor.Callback::class.java)
ambientLightModeMonitor.start(callback)
- // Monitor just started, should receive UNDECIDED.
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED)
+ verify(sensorManager).registerListener(any(), eq(sensor), anyInt())
+ }
- // Receives SensorEvent, and now mode is LIGHT.
+ @Test
+ fun shouldUnregisterSensorEventListenerOnStop() {
+ val callback = mock(AmbientLightModeMonitor.Callback::class.java)
+ ambientLightModeMonitor.start(callback)
+
val sensorEventListener = captureSensorEventListener()
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(15f))
- // Stop monitor.
ambientLightModeMonitor.stop()
- // Restart monitor.
- reset(callback)
- ambientLightModeMonitor.start(callback)
-
- // Verify receiving current mode (LIGHT) immediately.
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+ verify(sensorManager).unregisterListener(eq(sensorEventListener))
}
@Test
- fun shouldReportDarkModeWhenSensorValueIsLessThanTen() {
+ fun shouldStartDebounceAlgorithmOnStart() {
val callback = mock(AmbientLightModeMonitor.Callback::class.java)
ambientLightModeMonitor.start(callback)
- val sensorEventListener = captureSensorEventListener()
- reset(callback)
-
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(0f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
-
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(1f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
-
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(5f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
-
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(9.9f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+ verify(algorithm).start(eq(callback))
}
@Test
- fun shouldReportLightModeWhenSensorValueIsGreaterThanOrEqualToTen() {
+ fun shouldStopDebounceAlgorithmOnStop() {
val callback = mock(AmbientLightModeMonitor.Callback::class.java)
ambientLightModeMonitor.start(callback)
+ ambientLightModeMonitor.stop()
- val sensorEventListener = captureSensorEventListener()
- reset(callback)
-
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(10f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
-
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(10.1f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
-
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(15f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
-
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(100f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+ verify(algorithm).stop()
}
@Test
- fun shouldOnlyTriggerCallbackWhenValueChanges() {
+ fun shouldNotRegisterForSensorUpdatesIfSensorNotAvailable() {
+ `when`(sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)).thenReturn(null)
+ val ambientLightModeMonitor = AmbientLightModeMonitor(algorithm, sensorManager)
+
val callback = mock(AmbientLightModeMonitor.Callback::class.java)
ambientLightModeMonitor.start(callback)
- val sensorEventListener = captureSensorEventListener()
-
- // Light mode, should trigger callback.
- reset(callback)
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(20f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
-
- // Light mode again, should NOT trigger callback.
- reset(callback)
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(25f))
- verify(callback, never()).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
-
- // Dark mode, should trigger callback.
- reset(callback)
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(2f))
- verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
-
- // Dark mode again, should not trigger callback.
- reset(callback)
- sensorEventListener.onSensorChanged(sensorEventWithSingleValue(3f))
- verify(callback, never()).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+ verify(sensorManager, never()).registerListener(any(), any(Sensor::class.java), anyInt())
}
// Captures [SensorEventListener], assuming it has been registered with [sensorManager].
@@ -152,9 +108,4 @@
verify(sensorManager).registerListener(captor.capture(), any(), anyInt())
return captor.value
}
-
- // Returns a [SensorEvent] with a single [value].
- private fun sensorEventWithSingleValue(value: Float): SensorEvent {
- return SensorEvent(sensor, 1, 1, FloatArray(1) { value })
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/idle/LightSensorDebounceAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/idle/LightSensorDebounceAlgorithmTest.kt
new file mode 100644
index 0000000..ebc7345
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/idle/LightSensorDebounceAlgorithmTest.kt
@@ -0,0 +1,358 @@
+/*
+ * 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.systemui.idle
+
+import android.content.res.Resources
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.`when`
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class LightSensorDebounceAlgorithmTest : SysuiTestCase() {
+ @Mock private lateinit var resources: Resources
+
+ private val systemClock = FakeSystemClock()
+ private val executor = FakeExecutor(systemClock)
+
+ private lateinit var algorithm: LightSensorEventsDebounceAlgorithm
+
+ private val mockLightModeThreshold = 5
+ private val mockDarkModeThreshold = 2
+ private val mockLightModeSpan = 100
+ private val mockDarkModeSpan = 50
+ private val mockLightModeFrequency = 10
+ private val mockDarkModeFrequency = 5
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ `when`(resources.getInteger(R.integer.config_ambientLightModeThreshold))
+ .thenReturn(mockLightModeThreshold)
+ `when`(resources.getInteger(R.integer.config_ambientDarkModeThreshold))
+ .thenReturn(mockDarkModeThreshold)
+ `when`(resources.getInteger(R.integer.config_ambientLightModeSamplingSpanMillis))
+ .thenReturn(mockLightModeSpan)
+ `when`(resources.getInteger(R.integer.config_ambientDarkModeSamplingSpanMillis))
+ .thenReturn(mockDarkModeSpan)
+ `when`(resources.getInteger(R.integer.config_ambientLightModeSamplingFrequencyMillis))
+ .thenReturn(mockLightModeFrequency)
+ `when`(resources.getInteger(R.integer.config_ambientDarkModeSamplingFrequencyMillis))
+ .thenReturn(mockDarkModeFrequency)
+
+ algorithm = LightSensorEventsDebounceAlgorithm(executor, resources)
+ }
+
+ @Test
+ fun shouldOnlyTriggerCallbackWhenValueChanges() {
+ val callback = mock(AmbientLightModeMonitor.Callback::class.java)
+ algorithm.start(callback)
+
+ // Light mode, should trigger callback.
+ algorithm.mode = AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT
+ verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+ reset(callback)
+
+ // Light mode again, should NOT trigger callback.
+ algorithm.mode = AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT
+ verify(callback, never()).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+ reset(callback)
+
+ // Dark mode, should trigger callback.
+ algorithm.mode = AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK
+ verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+ reset(callback)
+
+ // Dark mode again, should not trigger callback.
+ algorithm.mode = AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK
+ verify(callback, never()).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+ }
+
+ @Test
+ fun shouldReportUndecidedWhenNeitherLightNorDarkClaimIsTrue() {
+ algorithm.isDarkMode = false
+ algorithm.isLightMode = false
+
+ assertThat(algorithm.mode).isEqualTo(
+ AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED)
+ }
+
+ @Test
+ fun shouldReportDarkModeAsLongAsDarkModeClaimIsTrue() {
+ algorithm.isDarkMode = true
+ algorithm.isLightMode = false
+
+ assertThat(algorithm.mode).isEqualTo(
+ AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+
+ algorithm.isLightMode = true
+ assertThat(algorithm.mode).isEqualTo(
+ AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+ }
+
+ @Test
+ fun shouldReportLightModeWhenLightModeClaimIsTrueAndDarkModeClaimIsFalse() {
+ algorithm.isLightMode = true
+ algorithm.isDarkMode = false
+
+ assertThat(algorithm.mode).isEqualTo(
+ AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+ }
+
+ @Test
+ fun shouldSetIsLightModeToTrueWhenBundleAverageIsGreaterThanThreshold() {
+ // Note: [mockLightModeThreshold] is 5.0.
+ algorithm.bundleAverageLightMode = 5.1
+ assertThat(algorithm.isLightMode).isTrue()
+
+ algorithm.bundleAverageLightMode = 10.0
+ assertThat(algorithm.isLightMode).isTrue()
+
+ algorithm.bundleAverageLightMode = 20.0
+ assertThat(algorithm.isLightMode).isTrue()
+
+ algorithm.bundleAverageLightMode = 5.0
+ assertThat(algorithm.isLightMode).isFalse()
+
+ algorithm.bundleAverageLightMode = 3.0
+ assertThat(algorithm.isLightMode).isFalse()
+
+ algorithm.bundleAverageLightMode = 0.0
+ assertThat(algorithm.isLightMode).isFalse()
+ }
+
+ @Test
+ fun shouldSetIsDarkModeToTrueWhenBundleAverageIsLessThanThreshold() {
+ // Note: [mockDarkModeThreshold] is 2.0.
+ algorithm.bundleAverageDarkMode = 1.9
+ assertThat(algorithm.isDarkMode).isTrue()
+
+ algorithm.bundleAverageDarkMode = 1.0
+ assertThat(algorithm.isDarkMode).isTrue()
+
+ algorithm.bundleAverageDarkMode = 0.0
+ assertThat(algorithm.isDarkMode).isTrue()
+
+ algorithm.bundleAverageDarkMode = 2.0
+ assertThat(algorithm.isDarkMode).isFalse()
+
+ algorithm.bundleAverageDarkMode = 3.0
+ assertThat(algorithm.isDarkMode).isFalse()
+
+ algorithm.bundleAverageDarkMode = 10.0
+ assertThat(algorithm.isDarkMode).isFalse()
+ }
+
+ @Test
+ fun shouldCorrectlyCalculateAverageFromABundle() {
+ // For light mode.
+ algorithm.bundleLightMode = arrayListOf(1.0f, 3.0f, 5.0f, 7.0f)
+ assertThat(algorithm.bundleAverageLightMode).isEqualTo(4.0)
+
+ algorithm.bundleLightMode = arrayListOf(2.0f, 4.0f, 6.0f, 8.0f)
+ assertThat(algorithm.bundleAverageLightMode).isEqualTo(5.0)
+
+ // For dark mode.
+ algorithm.bundleDarkMode = arrayListOf(1.0f, 3.0f, 5.0f, 7.0f, 9.0f)
+ assertThat(algorithm.bundleAverageDarkMode).isEqualTo(5.0)
+
+ algorithm.bundleDarkMode = arrayListOf(2.0f, 4.0f, 6.0f, 8.0f, 10.0f)
+ assertThat(algorithm.bundleAverageDarkMode).isEqualTo(6.0)
+ }
+
+ @Test
+ fun shouldAddSensorEventUpdatesToBundles() {
+ val callback = mock(AmbientLightModeMonitor.Callback::class.java)
+ // On start() one bundle is created for light and dark mode each.
+ algorithm.start(callback)
+ executor.runAllReady()
+
+ // Add 1 more bundle to queue for each mode.
+ algorithm.bundlesQueueLightMode.add(ArrayList())
+ algorithm.bundlesQueueDarkMode.add(ArrayList())
+
+ algorithm.onUpdateLightSensorEvent(1.0f)
+ algorithm.onUpdateLightSensorEvent(1.0f)
+ algorithm.onUpdateLightSensorEvent(2.0f)
+ algorithm.onUpdateLightSensorEvent(3.0f)
+ algorithm.onUpdateLightSensorEvent(4.0f)
+
+ val expectedValues = listOf(1.0f, 1.0f, 2.0f, 3.0f, 4.0f)
+
+ assertBundleContainsAll(algorithm.bundlesQueueLightMode[0], expectedValues)
+ assertBundleContainsAll(algorithm.bundlesQueueLightMode[1], expectedValues)
+ assertBundleContainsAll(algorithm.bundlesQueueDarkMode[0], expectedValues)
+ assertBundleContainsAll(algorithm.bundlesQueueDarkMode[1], expectedValues)
+ }
+
+ @Test
+ fun shouldCorrectlyEnqueueLightModeBundles() {
+ assertThat(algorithm.bundlesQueueLightMode.size).isEqualTo(0)
+
+ algorithm.enqueueLightModeBundle.run()
+ assertThat(algorithm.bundlesQueueLightMode.size).isEqualTo(1)
+
+ algorithm.enqueueLightModeBundle.run()
+ assertThat(algorithm.bundlesQueueLightMode.size).isEqualTo(2)
+
+ algorithm.enqueueLightModeBundle.run()
+ assertThat(algorithm.bundlesQueueLightMode.size).isEqualTo(3)
+
+ // Verifies dark mode bundles queue is not impacted.
+ assertThat(algorithm.bundlesQueueDarkMode.size).isEqualTo(0)
+ }
+
+ @Test
+ fun shouldCorrectlyEnqueueDarkModeBundles() {
+ assertThat(algorithm.bundlesQueueDarkMode.size).isEqualTo(0)
+
+ algorithm.enqueueDarkModeBundle.run()
+ assertThat(algorithm.bundlesQueueDarkMode.size).isEqualTo(1)
+
+ algorithm.enqueueDarkModeBundle.run()
+ assertThat(algorithm.bundlesQueueDarkMode.size).isEqualTo(2)
+
+ algorithm.enqueueDarkModeBundle.run()
+ assertThat(algorithm.bundlesQueueDarkMode.size).isEqualTo(3)
+
+ // Verifies light mode bundles queue is not impacted.
+ assertThat(algorithm.bundlesQueueLightMode.size).isEqualTo(0)
+ }
+
+ @Test
+ fun shouldCorrectlyDequeueLightModeBundles() {
+ // Sets up the light mode bundles queue.
+ val bundle1 = arrayListOf(1.0f, 3.0f, 6.0f, 9.0f)
+ val bundle2 = arrayListOf(5.0f, 10f)
+ val bundle3 = arrayListOf(2.0f, 4.0f)
+ algorithm.bundlesQueueLightMode.add(bundle1)
+ algorithm.bundlesQueueLightMode.add(bundle2)
+ algorithm.bundlesQueueLightMode.add(bundle3)
+
+ // The committed bundle should be the first one in queue.
+ algorithm.dequeueLightModeBundle.run()
+ assertBundleContainsAll(algorithm.bundleLightMode, bundle1)
+
+ algorithm.dequeueLightModeBundle.run()
+ assertBundleContainsAll(algorithm.bundleLightMode, bundle2)
+
+ algorithm.dequeueLightModeBundle.run()
+ assertBundleContainsAll(algorithm.bundleLightMode, bundle3)
+
+ // Verifies that the dark mode bundle is not impacted.
+ assertBundleContainsAll(algorithm.bundleDarkMode, listOf())
+ }
+
+ @Test
+ fun shouldCorrectlyDequeueDarkModeBundles() {
+ // Sets up the dark mode bundles queue.
+ val bundle1 = arrayListOf(2.0f, 4.0f)
+ val bundle2 = arrayListOf(5.0f, 10f)
+ val bundle3 = arrayListOf(1.0f, 3.0f, 6.0f, 9.0f)
+ algorithm.bundlesQueueDarkMode.add(bundle1)
+ algorithm.bundlesQueueDarkMode.add(bundle2)
+ algorithm.bundlesQueueDarkMode.add(bundle3)
+
+ // The committed bundle should be the first one in queue.
+ algorithm.dequeueDarkModeBundle.run()
+ assertBundleContainsAll(algorithm.bundleDarkMode, bundle1)
+
+ algorithm.dequeueDarkModeBundle.run()
+ assertBundleContainsAll(algorithm.bundleDarkMode, bundle2)
+
+ algorithm.dequeueDarkModeBundle.run()
+ assertBundleContainsAll(algorithm.bundleDarkMode, bundle3)
+
+ // Verifies that the light mode bundle is not impacted.
+ assertBundleContainsAll(algorithm.bundleLightMode, listOf())
+ }
+
+ @Test
+ fun shouldSetLightSensorLevelFromSensorEventUpdates() {
+ val callback = mock(AmbientLightModeMonitor.Callback::class.java)
+ algorithm.start(callback)
+
+ algorithm.onUpdateLightSensorEvent(1.0f)
+ assertThat(algorithm.lightSensorLevel).isEqualTo(1.0f)
+
+ algorithm.onUpdateLightSensorEvent(10.0f)
+ assertThat(algorithm.lightSensorLevel).isEqualTo(10.0f)
+
+ algorithm.onUpdateLightSensorEvent(0.0f)
+ assertThat(algorithm.lightSensorLevel).isEqualTo(0.0f)
+ }
+
+ @Test
+ fun shouldRippleFromSensorEventUpdatesDownToAmbientLightMode() {
+ val callback = mock(AmbientLightModeMonitor.Callback::class.java)
+ algorithm.start(callback)
+ executor.runAllReady()
+
+ // Sensor event updates.
+ algorithm.onUpdateLightSensorEvent(10.0f)
+ algorithm.onUpdateLightSensorEvent(15.0f)
+ algorithm.onUpdateLightSensorEvent(12.0f)
+ algorithm.onUpdateLightSensorEvent(10.0f)
+
+ // Advances time so both light and dark claims have been calculated.
+ systemClock.advanceTime((mockLightModeSpan + 1).toLong())
+
+ // Verifies the callback is triggered the ambient mode has changed LIGHT.
+ verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+ }
+
+ @Test
+ fun shouldRippleFromSensorEventUpdatesDownToAmbientDarkMode() {
+ val callback = mock(AmbientLightModeMonitor.Callback::class.java)
+ algorithm.start(callback)
+ executor.runAllReady()
+
+ // Sensor event updates.
+ algorithm.onUpdateLightSensorEvent(1.0f)
+ algorithm.onUpdateLightSensorEvent(0.5f)
+ algorithm.onUpdateLightSensorEvent(1.2f)
+ algorithm.onUpdateLightSensorEvent(0.8f)
+
+ // Advances time so both light and dark claims have been calculated.
+ systemClock.advanceTime((mockLightModeSpan + 1).toLong())
+
+ // Verifies the callback is triggered the ambient mode has changed DARK.
+ verify(callback).onChange(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+ }
+
+ // Asserts that [bundle] contains the same elements as [expected], not necessarily in the same
+ // order.
+ private fun assertBundleContainsAll(bundle: ArrayList<Float>, expected: Collection<Float>) {
+ assertThat(bundle.size).isEqualTo(expected.size)
+ assertThat(bundle.containsAll(expected))
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java
index c5436ef6..5e73dbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java
@@ -62,7 +62,8 @@
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import com.airbnb.lottie.LottieAnimationView;
@@ -97,11 +98,11 @@
private @Mock DumpManager mDumpManager;
private @Mock AccessibilityManager mAccessibilityManager;
private @Mock ConfigurationController mConfigurationController;
- private @Mock DelayableExecutor mDelayableExecutor;
private @Mock Vibrator mVibrator;
private @Mock AuthRippleController mAuthRippleController;
private @Mock LottieAnimationView mAodFp;
private @Mock LayoutInflater mLayoutInflater;
+ private FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
private LockIconViewController mLockIconViewController;
@@ -223,6 +224,7 @@
// WHEN all authenticators are registered
mAuthControllerCallback.onAllAuthenticatorsRegistered();
+ mDelayableExecutor.runAllReady();
// THEN lock icon view location is updated with the same coordinates as fpProps
verify(mLockIconView).setCenterLocation(mPointCaptor.capture(), eq(udfps.first));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
index 39d794d..ebeb591 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
@@ -60,6 +60,7 @@
import android.util.ArraySet;
import android.util.Pair;
+import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
@@ -1405,25 +1406,26 @@
mName = name;
}
+ @NonNull
@Override
public String getName() {
return mName;
}
@Override
- public void setCallback(OnEndLifetimeExtensionCallback callback) {
+ public void setCallback(@NonNull OnEndLifetimeExtensionCallback callback) {
this.callback = callback;
}
@Override
public boolean shouldExtendLifetime(
- NotificationEntry entry,
+ @NonNull NotificationEntry entry,
@CancellationReason int reason) {
return shouldExtendLifetime;
}
@Override
- public void cancelLifetimeExtension(NotificationEntry entry) {
+ public void cancelLifetimeExtension(@NonNull NotificationEntry entry) {
if (onCancelLifetimeExtension != null) {
onCancelLifetimeExtension.run();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt
new file mode 100644
index 0000000..0cba0703
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.systemui.statusbar.notification.collection.coordinator
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender.OnEndLifetimeExtensionCallback
+import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewListener
+import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager
+import com.android.systemui.statusbar.notification.row.NotificationGuts
+import com.android.systemui.util.mockito.argumentCaptor
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations.initMocks
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+class GutsCoordinatorTest : SysuiTestCase() {
+ private lateinit var coordinator: GutsCoordinator
+ private lateinit var notifLifetimeExtender: NotifLifetimeExtender
+ private lateinit var notifGutsViewListener: NotifGutsViewListener
+
+ private lateinit var entry1: NotificationEntry
+ private lateinit var entry2: NotificationEntry
+
+ @Mock private lateinit var notifGutsViewManager: NotifGutsViewManager
+ @Mock private lateinit var pipeline: NotifPipeline
+ @Mock private lateinit var dumpManager: DumpManager
+ @Mock private lateinit var logger: GutsCoordinatorLogger
+ @Mock private lateinit var lifetimeExtenderCallback: OnEndLifetimeExtensionCallback
+
+ @Before
+ fun setUp() {
+ initMocks(this)
+ coordinator = GutsCoordinator(notifGutsViewManager, logger, dumpManager)
+ coordinator.attach(pipeline)
+ notifLifetimeExtender = argumentCaptor<NotifLifetimeExtender>().let {
+ verify(pipeline).addNotificationLifetimeExtender(it.capture())
+ it.value!!
+ }
+ notifGutsViewListener = argumentCaptor<NotifGutsViewListener>().let {
+ verify(notifGutsViewManager).setGutsListener(it.capture())
+ it.value!!
+ }
+ notifLifetimeExtender.setCallback(lifetimeExtenderCallback)
+ entry1 = NotificationEntryBuilder().setId(1).build()
+ entry2 = NotificationEntryBuilder().setId(2).build()
+ }
+
+ @Test
+ fun testSimpleLifetimeExtension() {
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isFalse()
+ notifGutsViewListener.onGutsOpen(entry1, mock(NotificationGuts::class.java))
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isTrue()
+ notifGutsViewListener.onGutsClose(entry1)
+ verify(lifetimeExtenderCallback).onEndLifetimeExtension(notifLifetimeExtender, entry1)
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isFalse()
+ }
+
+ @Test
+ fun testDoubleOpenLifetimeExtension() {
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isFalse()
+ notifGutsViewListener.onGutsOpen(entry1, mock(NotificationGuts::class.java))
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isTrue()
+ notifGutsViewListener.onGutsOpen(entry1, mock(NotificationGuts::class.java))
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isTrue()
+ notifGutsViewListener.onGutsClose(entry1)
+ verify(lifetimeExtenderCallback).onEndLifetimeExtension(notifLifetimeExtender, entry1)
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isFalse()
+ }
+
+ @Test
+ fun testTwoEntryLifetimeExtension() {
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isFalse()
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry2, 0)).isFalse()
+ notifGutsViewListener.onGutsOpen(entry1, mock(NotificationGuts::class.java))
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isTrue()
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry2, 0)).isFalse()
+ notifGutsViewListener.onGutsOpen(entry2, mock(NotificationGuts::class.java))
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isTrue()
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry2, 0)).isTrue()
+ notifGutsViewListener.onGutsClose(entry1)
+ verify(lifetimeExtenderCallback).onEndLifetimeExtension(notifLifetimeExtender, entry1)
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isFalse()
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry2, 0)).isTrue()
+ notifGutsViewListener.onGutsClose(entry2)
+ verify(lifetimeExtenderCallback).onEndLifetimeExtension(notifLifetimeExtender, entry2)
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry1, 0)).isFalse()
+ assertThat(notifLifetimeExtender.shouldExtendLifetime(entry2, 0)).isFalse()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 033f689..310a8ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -19,19 +19,25 @@
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.ViewGroup
+import android.view.ViewTreeObserver
+import android.view.ViewTreeObserver.OnPreDrawListener
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import com.android.systemui.util.mockito.any
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
+import org.mockito.ArgumentCaptor
import org.mockito.Mock
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.verify
-import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
@SmallTest
@@ -48,10 +54,14 @@
@Mock
private lateinit var moveFromCenterAnimation: StatusBarMoveFromCenterAnimationController
+ @Mock
+ private lateinit var progressProvider: ScopedUnfoldTransitionProgressProvider
private lateinit var view: PhoneStatusBarView
private lateinit var controller: PhoneStatusBarViewController
+ private val unfoldConfig = UnfoldConfig()
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
@@ -66,11 +76,7 @@
view.setBar(mock(StatusBar::class.java))
}
- controller = PhoneStatusBarViewController(
- view,
- null,
- touchEventHandler,
- )
+ controller = createController(view)
}
@Test
@@ -83,12 +89,38 @@
}
@Test
- fun constructor_moveFromCenterAnimationIsNotNull_moveFromCenterAnimationInitialized() {
- controller = PhoneStatusBarViewController(
- view, moveFromCenterAnimation, touchEventHandler
- )
+ fun onViewAttachedAndDrawn_moveFromCenterAnimationEnabled_moveFromCenterAnimationInitialized() {
+ val view = createViewMock()
+ val argumentCaptor = ArgumentCaptor.forClass(OnPreDrawListener::class.java)
+ unfoldConfig.isEnabled = true
+ controller = createController(view)
+ controller.init()
- verify(moveFromCenterAnimation).init(any(), any())
+ verify(view.viewTreeObserver).addOnPreDrawListener(argumentCaptor.capture())
+ argumentCaptor.value.onPreDraw()
+
+ verify(moveFromCenterAnimation).onViewsReady(any(), any())
+ }
+
+ private fun createViewMock(): PhoneStatusBarView {
+ val view = spy(view)
+ val viewTreeObserver = mock(ViewTreeObserver::class.java)
+ `when`(view.viewTreeObserver).thenReturn(viewTreeObserver)
+ `when`(view.isAttachedToWindow).thenReturn(true)
+ return view
+ }
+
+ private fun createController(view: PhoneStatusBarView): PhoneStatusBarViewController {
+ return PhoneStatusBarViewController.Factory(
+ { progressProvider },
+ { moveFromCenterAnimation },
+ unfoldConfig
+ ).create(view, touchEventHandler)
+ }
+
+ private class UnfoldConfig : UnfoldTransitionConfig {
+ override var isEnabled: Boolean = false
+ override var isHingeAngleEnabled: Boolean = false
}
private class TestTouchEventHandler : PhoneStatusBarView.TouchEventHandler {
@@ -97,6 +129,5 @@
lastEvent = event
return false
}
-
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 40e9b0c..943d3c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -144,6 +144,7 @@
import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation;
import com.android.systemui.unfold.UnfoldTransitionWallpaperController;
import com.android.systemui.unfold.config.UnfoldTransitionConfig;
+import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
import com.android.systemui.util.WallpaperController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.concurrency.MessageRouterImpl;
@@ -259,7 +260,7 @@
@Mock private BrightnessSlider.Factory mBrightnessSliderFactory;
@Mock private UnfoldTransitionConfig mUnfoldTransitionConfig;
@Mock private Lazy<UnfoldLightRevealOverlayAnimation> mUnfoldLightRevealOverlayAnimationLazy;
- @Mock private Lazy<StatusBarMoveFromCenterAnimationController> mMoveFromCenterAnimationLazy;
+ @Mock private Lazy<NaturalRotationUnfoldProgressProvider> mNaturalRotationProgressProvider;
@Mock private Lazy<UnfoldTransitionWallpaperController> mUnfoldWallpaperController;
@Mock private WallpaperController mWallpaperController;
@Mock private OngoingCallController mOngoingCallController;
@@ -276,6 +277,7 @@
@Mock private StartingSurface mStartingSurface;
@Mock private OperatorNameViewController mOperatorNameViewController;
@Mock private OperatorNameViewController.Factory mOperatorNameViewControllerFactory;
+ @Mock private PhoneStatusBarViewController.Factory mPhoneStatusBarViewControllerFactory;
@Mock private ActivityLaunchAnimator mActivityLaunchAnimator;
@Mock private DialogLaunchAnimator mDialogLaunchAnimator;
private ShadeController mShadeController;
@@ -429,6 +431,7 @@
mExtensionController,
mUserInfoControllerImpl,
mOperatorNameViewControllerFactory,
+ mPhoneStatusBarViewControllerFactory,
mPhoneStatusBarPolicy,
mKeyguardIndicationController,
mDemoModeController,
@@ -439,7 +442,7 @@
mUnfoldTransitionConfig,
mUnfoldLightRevealOverlayAnimationLazy,
mUnfoldWallpaperController,
- mMoveFromCenterAnimationLazy,
+ mNaturalRotationProgressProvider,
mWallpaperController,
mOngoingCallController,
mAnimationScheduler,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
new file mode 100644
index 0000000..a3f17aa
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
@@ -0,0 +1,139 @@
+/*
+ * 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.systemui.unfold.util
+
+import android.testing.AndroidTestingRunner
+import android.view.IRotationWatcher
+import android.view.IWindowManager
+import android.view.Surface
+import androidx.test.filters.SmallTest
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.util.mockito.any
+import com.android.systemui.SysuiTestCase
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class NaturalRotationUnfoldProgressProviderTest : SysuiTestCase() {
+
+ @Mock
+ lateinit var windowManager: IWindowManager
+
+ @Mock
+ lateinit var sourceProvider: UnfoldTransitionProgressProvider
+
+ @Mock
+ lateinit var transitionListener: TransitionProgressListener
+
+ lateinit var progressProvider: NaturalRotationUnfoldProgressProvider
+
+ private val sourceProviderListenerCaptor =
+ ArgumentCaptor.forClass(TransitionProgressListener::class.java)
+ private val rotationWatcherCaptor =
+ ArgumentCaptor.forClass(IRotationWatcher.Stub::class.java)
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ progressProvider = NaturalRotationUnfoldProgressProvider(
+ context,
+ windowManager,
+ sourceProvider
+ )
+
+ progressProvider.init()
+
+ verify(sourceProvider).addCallback(sourceProviderListenerCaptor.capture())
+ verify(windowManager).watchRotation(rotationWatcherCaptor.capture(), any())
+
+ progressProvider.addCallback(transitionListener)
+ }
+
+ @Test
+ fun testNaturalRotation0_sendTransitionStartedEvent_eventReceived() {
+ onRotationChanged(Surface.ROTATION_0)
+
+ source.onTransitionStarted()
+
+ verify(transitionListener).onTransitionStarted()
+ }
+
+ @Test
+ fun testNaturalRotation0_sendTransitionProgressEvent_eventReceived() {
+ onRotationChanged(Surface.ROTATION_0)
+
+ source.onTransitionProgress(0.5f)
+
+ verify(transitionListener).onTransitionProgress(0.5f)
+ }
+
+ @Test
+ fun testNotNaturalRotation90_sendTransitionStartedEvent_eventNotReceived() {
+ onRotationChanged(Surface.ROTATION_90)
+
+ source.onTransitionStarted()
+
+ verify(transitionListener, never()).onTransitionStarted()
+ }
+
+ @Test
+ fun testNaturalRotation90_sendTransitionProgressEvent_eventNotReceived() {
+ onRotationChanged(Surface.ROTATION_90)
+
+ source.onTransitionProgress(0.5f)
+
+ verify(transitionListener, never()).onTransitionProgress(0.5f)
+ }
+
+ @Test
+ fun testRotationBecameUnnaturalDuringTransition_sendsTransitionFinishedEvent() {
+ onRotationChanged(Surface.ROTATION_0)
+ source.onTransitionStarted()
+ clearInvocations(transitionListener)
+
+ onRotationChanged(Surface.ROTATION_90)
+
+ verify(transitionListener).onTransitionFinished()
+ }
+
+ @Test
+ fun testRotationBecameNaturalDuringTransition_sendsTransitionStartedEvent() {
+ onRotationChanged(Surface.ROTATION_90)
+ source.onTransitionStarted()
+ clearInvocations(transitionListener)
+
+ onRotationChanged(Surface.ROTATION_0)
+
+ verify(transitionListener).onTransitionStarted()
+ }
+
+ private fun onRotationChanged(rotation: Int) {
+ rotationWatcherCaptor.value.onRotationChanged(rotation)
+ }
+
+ private val source: TransitionProgressListener
+ get() = sourceProviderListenerCaptor.value
+}
diff --git a/proto/src/critical_event_log.proto b/proto/src/criticalevents/critical_event_log.proto
similarity index 97%
rename from proto/src/critical_event_log.proto
rename to proto/src/criticalevents/critical_event_log.proto
index cb05a71..27787c2 100644
--- a/proto/src/critical_event_log.proto
+++ b/proto/src/criticalevents/critical_event_log.proto
@@ -15,7 +15,7 @@
*/
syntax = "proto2";
-package com.android.server.am;
+package com.android.server.criticalevents;
option java_multiple_files = true;
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index a418e70..a48172b 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -21,11 +21,12 @@
import static android.bluetooth.le.ScanSettings.SCAN_MODE_BALANCED;
import static android.companion.AssociationRequest.DEVICE_PROFILE_APP_STREAMING;
import static android.companion.AssociationRequest.DEVICE_PROFILE_WATCH;
+import static android.companion.DeviceId.TYPE_MAC_ADDRESS;
import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static com.android.internal.util.CollectionUtils.add;
import static com.android.internal.util.CollectionUtils.any;
-import static com.android.internal.util.CollectionUtils.emptyIfNull;
import static com.android.internal.util.CollectionUtils.filter;
import static com.android.internal.util.CollectionUtils.find;
import static com.android.internal.util.CollectionUtils.forEach;
@@ -37,6 +38,9 @@
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.unmodifiableMap;
+import static java.util.Collections.unmodifiableSet;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MINUTES;
@@ -45,6 +49,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
+import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.NotificationManager;
@@ -60,6 +65,7 @@
import android.companion.Association;
import android.companion.AssociationRequest;
import android.companion.CompanionDeviceManager;
+import android.companion.DeviceId;
import android.companion.DeviceNotAssociatedException;
import android.companion.ICompanionDeviceDiscoveryService;
import android.companion.ICompanionDeviceManager;
@@ -90,20 +96,17 @@
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ShellCallback;
-import android.os.ShellCommand;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionControllerManager;
import android.text.BidiFormatter;
import android.util.ArrayMap;
import android.util.ArraySet;
-import android.util.AtomicFile;
import android.util.ExceptionUtils;
-import android.util.Log;
import android.util.PackageUtils;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.Xml;
+import android.util.SparseBooleanArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
@@ -123,35 +126,29 @@
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TimeZone;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
+import java.util.function.Predicate;
/** @hide */
@SuppressLint("LongLogTag")
public class CompanionDeviceManagerService extends SystemService implements Binder.DeathRecipient {
+ static final String LOG_TAG = "CompanionDeviceManagerService";
+ static final boolean DEBUG = false;
private static final Map<String, String> DEVICE_PROFILE_TO_PERMISSION;
static {
@@ -160,9 +157,12 @@
map.put(DEVICE_PROFILE_APP_STREAMING,
Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING);
- DEVICE_PROFILE_TO_PERMISSION = Collections.unmodifiableMap(map);
+ DEVICE_PROFILE_TO_PERMISSION = unmodifiableMap(map);
}
+ /** Range of Association IDs allocated for a user.*/
+ static final int ASSOCIATIONS_IDS_PER_USER_RANGE = 100000;
+
private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative(
CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
".CompanionDeviceDiscoveryService");
@@ -172,9 +172,6 @@
static final long DEVICE_LISTENER_DIED_REBIND_TIMEOUT_MS = 10 * 1000;
- private static final boolean DEBUG = false;
- private static final String LOG_TAG = "CompanionDeviceManagerService";
-
private static final long PAIR_WITHOUT_PROMPT_WINDOW_MS = 10 * 60 * 1000; // 10 min
private static final String PREF_FILE_NAME = "companion_device_preferences.xml";
@@ -183,22 +180,14 @@
private static final int ASSOCIATE_WITHOUT_PROMPT_MAX_PER_TIME_WINDOW = 5;
private static final long ASSOCIATE_WITHOUT_PROMPT_WINDOW_MS = 60 * 60 * 1000; // 60 min;
- private static final String XML_TAG_ASSOCIATIONS = "associations";
- private static final String XML_TAG_ASSOCIATION = "association";
- private static final String XML_ATTR_PACKAGE = "package";
- private static final String XML_ATTR_DEVICE = "device";
- private static final String XML_ATTR_PROFILE = "profile";
- private static final String XML_ATTR_NOTIFY_DEVICE_NEARBY = "notify_device_nearby";
- private static final String XML_ATTR_TIME_APPROVED = "time_approved";
- private static final String XML_FILE_NAME = "companion_device_manager_associations.xml";
-
private static DateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
static {
sDateFormat.setTimeZone(TimeZone.getDefault());
}
private final CompanionDeviceManagerImpl mImpl;
- private final ConcurrentMap<Integer, AtomicFile> mUidToStorage = new ConcurrentHashMap<>();
+ // Persistent data store for all Associations.
+ private final PersistentDataStore mPersistentDataStore;
private PowerWhitelistManager mPowerWhitelistManager;
private PerUser<ServiceConnector<ICompanionDeviceDiscoveryService>> mServiceConnectors;
private IAppOpsService mAppOpsManager;
@@ -227,9 +216,17 @@
private final Handler mMainHandler = Handler.getMain();
private CompanionDevicePresenceController mCompanionDevicePresenceController;
- /** userId -> [association] */
+ /** Maps a {@link UserIdInt} to a set of associations for the user. */
@GuardedBy("mLock")
- private @Nullable SparseArray<Set<Association>> mCachedAssociations = new SparseArray<>();
+ private final SparseArray<Set<Association>> mCachedAssociations = new SparseArray<>();
+ /**
+ * A structure that consist of two nested maps, and effectively maps (userId + packageName) to
+ * a list of IDs that have been previously assigned to associations for that package.
+ * We maintain this structure so that we never re-use association IDs for the same package
+ * (until it's uninstalled).
+ */
+ @GuardedBy("mLock")
+ private final SparseArray<Map<String, Set<Integer>>> mPreviouslyUsedIds = new SparseArray<>();
ActivityTaskManagerInternal mAtmInternal;
ActivityManagerInternal mAmInternal;
@@ -238,6 +235,8 @@
public CompanionDeviceManagerService(Context context) {
super(context);
mImpl = new CompanionDeviceManagerImpl();
+ mPersistentDataStore = new PersistentDataStore();
+
mPowerWhitelistManager = context.getSystemService(PowerWhitelistManager.class);
mRoleManager = context.getSystemService(RoleManager.class);
mAppOpsManager = IAppOpsService.Stub.asInterface(
@@ -272,8 +271,7 @@
+ ", uid = " + uid + ")");
int userId = getChangingUserId();
updateAssociations(
- as -> CollectionUtils.filter(as,
- a -> !Objects.equals(a.getPackageName(), packageName)),
+ set -> filterOut(set, it -> it.belongsToPackage(userId, packageName)),
userId);
mCompanionDevicePresenceController.unbindDevicePresenceListener(
@@ -447,9 +445,8 @@
}, FgThread.getExecutor()).whenComplete(uncheckExceptions((deviceAddress, err) -> {
if (err == null) {
- Association association = new Association(userId, deviceAddress, callingPackage,
- deviceProfile, false, System.currentTimeMillis());
- addAssociation(association, userId);
+ createAssociationInternal(
+ userId, deviceAddress, callingPackage, deviceProfile);
} else {
Slog.e(LOG_TAG, "Failed to discover device(s)", err);
callback.onFailure("No devices found: " + err.getMessage());
@@ -633,7 +630,7 @@
checkCallerIsSystemOr(packageName);
int userId = getCallingUserId();
- Set<Association> deviceAssociations = CollectionUtils.filter(
+ Set<Association> deviceAssociations = filter(
getAllAssociations(userId, packageName),
association -> deviceAddress.equals(association.getDeviceMacAddress()));
@@ -646,16 +643,9 @@
updateAssociations(associations -> map(associations, association -> {
if (Objects.equals(association.getPackageName(), packageName)
&& Objects.equals(association.getDeviceMacAddress(), deviceAddress)) {
- return new Association(
- association.getUserId(),
- association.getDeviceMacAddress(),
- association.getPackageName(),
- association.getDeviceProfile(),
- active /* notifyOnDeviceNearby */,
- association.getTimeApprovedMs());
- } else {
- return association;
+ association.setNotifyOnDeviceNearby(active);
}
+ return association;
}), userId);
restartBleScan();
@@ -673,9 +663,7 @@
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES, "createAssociation");
- addAssociation(new Association(
- userId, macAddress, packageName, null, false,
- System.currentTimeMillis()), userId);
+ createAssociationInternal(userId, macAddress, packageName, null);
}
private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
@@ -706,7 +694,7 @@
@Override
public boolean canPairWithoutPrompt(
String packageName, String deviceMacAddress, int userId) {
- return CollectionUtils.any(
+ return any(
getAllAssociations(userId, packageName, deviceMacAddress),
a -> System.currentTimeMillis() - a.getTimeApprovedMs()
< PAIR_WITHOUT_PROMPT_WINDOW_MS);
@@ -716,7 +704,10 @@
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ShellCallback callback, ResultReceiver resultReceiver)
throws RemoteException {
- new ShellCmd().exec(this, in, out, err, args, callback, resultReceiver);
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_COMPANION_DEVICES, null);
+ new CompanionDeviceShellCommand(CompanionDeviceManagerService.this)
+ .exec(this, in, out, err, args, callback, resultReceiver);
}
@Override
@@ -779,24 +770,87 @@
return Binder.getCallingUid() == Process.SYSTEM_UID;
}
- void addAssociation(Association association, int userId) {
+ void createAssociationInternal(
+ int userId, String deviceMacAddress, String packageName, String deviceProfile) {
+ final Association association = new Association(
+ getNewAssociationIdForPackage(userId, packageName),
+ userId,
+ packageName,
+ Arrays.asList(new DeviceId(TYPE_MAC_ADDRESS, deviceMacAddress)),
+ deviceProfile,
+ /* managedByCompanionApp */false,
+ /* notifyOnDeviceNearby */ false ,
+ System.currentTimeMillis());
+
updateSpecialAccessPermissionForAssociatedPackage(association);
recordAssociation(association, userId);
}
- void removeAssociation(int userId, String pkg, String deviceMacAddress) {
- updateAssociations(associations -> CollectionUtils.filter(associations, association -> {
- boolean notMatch = association.getUserId() != userId
- || !Objects.equals(association.getDeviceMacAddress(), deviceMacAddress)
- || !Objects.equals(association.getPackageName(), pkg);
- if (!notMatch) {
- onAssociationPreRemove(association);
+ @GuardedBy("mLock")
+ @NonNull
+ private Set<Integer> getPreviouslyUsedIdsForPackageLocked(
+ @UserIdInt int userId, @NonNull String packageName) {
+ final Set<Integer> previouslyUsedIds = mPreviouslyUsedIds.get(userId).get(packageName);
+ if (previouslyUsedIds != null) return previouslyUsedIds;
+ return emptySet();
+ }
+
+ private int getNewAssociationIdForPackage(@UserIdInt int userId, @NonNull String packageName) {
+ synchronized (mLock) {
+ readPersistedStateForUserIfNeededLocked(userId);
+
+ // First: collect all IDs currently in use for this user's Associations.
+ final SparseBooleanArray usedIds = new SparseBooleanArray();
+ for (Association it : getAllAssociations(userId)) {
+ usedIds.put(it.getAssociationId(), true);
}
- return notMatch;
+
+ // Second: collect all IDs that have been previously used for this package (and user).
+ final Set<Integer> previouslyUsedIds =
+ getPreviouslyUsedIdsForPackageLocked(userId, packageName);
+
+ int id = getFirstAssociationIdForUser(userId);
+ final int lastAvailableIdForUser = getLastAssociationIdForUser(userId);
+
+ // Find first ID that isn't used now AND has never been used for the given package.
+ while (usedIds.get(id) || previouslyUsedIds.contains(id)) {
+ // Increment and try again
+ id++;
+ // ... but first check if the ID is valid (within the range allocated to the user).
+ if (id > lastAvailableIdForUser) {
+ throw new RuntimeException("Cannot create a new Association ID for "
+ + packageName + " for user " + userId);
+ }
+ }
+
+ return id;
+ }
+ }
+
+ void removeAssociation(int userId, String packageName, String deviceMacAddress) {
+ updateAssociations(associations -> filterOut(associations, it -> {
+ final boolean match = it.belongsToPackage(userId, packageName)
+ && Objects.equals(it.getDeviceMacAddress(), deviceMacAddress);
+ if (match) {
+ onAssociationPreRemove(it);
+ markIdAsPreviouslyUsedForPackage(it.getAssociationId(), userId, packageName);
+ }
+ return match;
}), userId);
restartBleScan();
}
+ private void markIdAsPreviouslyUsedForPackage(
+ int associationId, @UserIdInt int userId, @NonNull String packageName) {
+ synchronized (mLock) {
+ // Mark as previously used.
+ readPersistedStateForUserIfNeededLocked(userId);
+ mPreviouslyUsedIds.get(userId)
+ .computeIfAbsent(packageName, it -> new HashSet<>())
+ .add(associationId);
+ }
+ }
+
void onAssociationPreRemove(Association association) {
if (association.isNotifyOnDeviceNearby()) {
mCompanionDevicePresenceController.unbindDevicePresenceListener(
@@ -983,22 +1037,31 @@
private void recordAssociation(Association association, int userId) {
Slog.i(LOG_TAG, "recordAssociation(" + association + ")");
- updateAssociations(associations -> CollectionUtils.add(associations, association), userId);
+ updateAssociations(associations -> add(associations, association), userId);
}
private void updateAssociations(Function<Set<Association>, Set<Association>> update,
int userId) {
synchronized (mLock) {
- final Set<Association> old = getAllAssociations(userId);
- Set<Association> associations = new ArraySet<>(old);
- associations = update.apply(associations);
- Slog.i(LOG_TAG, "Updating associations: " + old + " --> " + associations);
- mCachedAssociations.put(userId, Collections.unmodifiableSet(associations));
- BackgroundThread.getHandler().sendMessage(PooledLambda.obtainMessage(
- CompanionDeviceManagerService::persistAssociations,
- this, associations, userId));
+ if (DEBUG) Slog.d(LOG_TAG, "Updating Associations set...");
- updateAtm(userId, associations);
+ final Set<Association> prevAssociations = getAllAssociations(userId);
+ if (DEBUG) Slog.d(LOG_TAG, " > Before : " + prevAssociations + "...");
+
+ final Set<Association> updatedAssociations = update.apply(
+ new ArraySet<>(prevAssociations));
+ if (DEBUG) Slog.d(LOG_TAG, " > After: " + updatedAssociations);
+
+ mCachedAssociations.put(userId, unmodifiableSet(updatedAssociations));
+
+ BackgroundThread.getHandler().sendMessage(
+ PooledLambda.obtainMessage(
+ (associations, usedIds) ->
+ mPersistentDataStore
+ .persistStateForUser(userId, associations, usedIds),
+ updatedAssociations, deepCopy(mPreviouslyUsedIds.get(userId))));
+
+ updateAtm(userId, updatedAssociations);
}
}
@@ -1020,64 +1083,34 @@
}
}
- private void persistAssociations(Set<Association> associations, int userId) {
- Slog.i(LOG_TAG, "Writing associations to disk: " + associations);
- final AtomicFile file = getStorageFileForUser(userId);
- synchronized (file) {
- file.write(out -> {
- XmlSerializer xml = Xml.newSerializer();
- try {
- xml.setOutput(out, StandardCharsets.UTF_8.name());
- xml.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
- xml.startDocument(null, true);
- xml.startTag(null, XML_TAG_ASSOCIATIONS);
-
- forEach(associations, association -> {
- XmlSerializer tag = xml.startTag(null, XML_TAG_ASSOCIATION)
- .attribute(null, XML_ATTR_PACKAGE, association.getPackageName())
- .attribute(null, XML_ATTR_DEVICE,
- association.getDeviceMacAddress());
- if (association.getDeviceProfile() != null) {
- tag.attribute(null, XML_ATTR_PROFILE, association.getDeviceProfile());
- tag.attribute(null, XML_ATTR_NOTIFY_DEVICE_NEARBY,
- Boolean.toString(
- association.isNotifyOnDeviceNearby()));
- }
- tag.attribute(null, XML_ATTR_TIME_APPROVED,
- Long.toString(association.getTimeApprovedMs()));
- tag.endTag(null, XML_TAG_ASSOCIATION);
- });
-
- xml.endTag(null, XML_TAG_ASSOCIATIONS);
- xml.endDocument();
- } catch (Exception e) {
- Slog.e(LOG_TAG, "Error while writing associations file", e);
- throw ExceptionUtils.propagate(e);
- }
- });
- }
- }
-
- private AtomicFile getStorageFileForUser(int userId) {
- return mUidToStorage.computeIfAbsent(userId, (u) ->
- new AtomicFile(new File(
- //TODO deprecated method - what's the right replacement?
- Environment.getUserSystemDirectory(u),
- XML_FILE_NAME)));
- }
-
- @Nullable
- private Set<Association> getAllAssociations(int userId) {
+ @NonNull Set<Association> getAllAssociations(int userId) {
synchronized (mLock) {
- if (mCachedAssociations.get(userId) == null) {
- mCachedAssociations.put(userId, Collections.unmodifiableSet(
- emptyIfNull(readAllAssociations(userId))));
- Slog.i(LOG_TAG, "Read associations from disk: " + mCachedAssociations);
- }
+ readPersistedStateForUserIfNeededLocked(userId);
+ // This returns non-null, because the readAssociationsInfoForUserIfNeededLocked() method
+ // we just called adds an empty set, if there was no previously saved data.
return mCachedAssociations.get(userId);
}
}
+ @GuardedBy("mLock")
+ private void readPersistedStateForUserIfNeededLocked(@UserIdInt int userId) {
+ if (mCachedAssociations.get(userId) != null) return;
+
+ Slog.i(LOG_TAG, "Reading state for user " + userId + " from the disk");
+
+ final Set<Association> associations = new ArraySet<>();
+ final Map<String, Set<Integer>> previouslyUsedIds = new ArrayMap<>();
+ mPersistentDataStore.readStateForUser(userId, associations, previouslyUsedIds);
+
+ if (DEBUG) {
+ Slog.d(LOG_TAG, " > associations=" + associations + "\n"
+ + " > previouslyUsedIds=" + previouslyUsedIds);
+ }
+
+ mCachedAssociations.put(userId, unmodifiableSet(associations));
+ mPreviouslyUsedIds.append(userId, previouslyUsedIds);
+ }
+
private List<UserInfo> getAllUsers() {
final long identity = Binder.clearCallingIdentity();
try {
@@ -1088,7 +1121,7 @@
}
private Set<Association> getAllAssociations(int userId, @Nullable String packageFilter) {
- return CollectionUtils.filter(
+ return filter(
getAllAssociations(userId),
// Null filter == get all associations
a -> packageFilter == null || Objects.equals(packageFilter, a.getPackageName()));
@@ -1107,10 +1140,9 @@
}
}
-
private Set<Association> getAllAssociations(
int userId, @Nullable String packageFilter, @Nullable String addressFilter) {
- return CollectionUtils.filter(
+ return filter(
getAllAssociations(userId),
// Null filter == get all associations
a -> (packageFilter == null || Objects.equals(packageFilter, a.getPackageName()))
@@ -1118,44 +1150,6 @@
|| Objects.equals(addressFilter, a.getDeviceMacAddress())));
}
- private Set<Association> readAllAssociations(int userId) {
- final AtomicFile file = getStorageFileForUser(userId);
-
- if (!file.getBaseFile().exists()) return null;
-
- ArraySet<Association> result = null;
- final XmlPullParser parser = Xml.newPullParser();
- synchronized (file) {
- try (FileInputStream in = file.openRead()) {
- parser.setInput(in, StandardCharsets.UTF_8.name());
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (type != XmlPullParser.START_TAG
- && !XML_TAG_ASSOCIATIONS.equals(parser.getName())) continue;
-
- final String appPackage = parser.getAttributeValue(null, XML_ATTR_PACKAGE);
- final String deviceAddress = parser.getAttributeValue(null, XML_ATTR_DEVICE);
-
- final String profile = parser.getAttributeValue(null, XML_ATTR_PROFILE);
- final boolean persistentGrants = Boolean.valueOf(
- parser.getAttributeValue(null, XML_ATTR_NOTIFY_DEVICE_NEARBY));
- final long timeApproved = parseLongOrDefault(
- parser.getAttributeValue(null, XML_ATTR_TIME_APPROVED), 0L);
-
- if (appPackage == null || deviceAddress == null) continue;
-
- result = ArrayUtils.add(result,
- new Association(userId, deviceAddress, appPackage,
- profile, persistentGrants, timeApproved));
- }
- return result;
- } catch (XmlPullParserException | IOException e) {
- Slog.e(LOG_TAG, "Error while reading associations file", e);
- return null;
- }
- }
- }
-
void onDeviceConnected(String address) {
Slog.d(LOG_TAG, "onDeviceConnected(address = " + address + ")");
@@ -1469,86 +1463,15 @@
return result;
}
- private static long parseLongOrDefault(String str, long def) {
- try {
- return Long.parseLong(str);
- } catch (NumberFormatException e) {
- Slog.w(LOG_TAG, "Failed to parse", e);
- return def;
- }
+ static int getFirstAssociationIdForUser(@UserIdInt int userId) {
+ // We want the IDs to start from 1, not 0.
+ return userId * ASSOCIATIONS_IDS_PER_USER_RANGE + 1;
}
- private class ShellCmd extends ShellCommand {
- public static final String USAGE = "help\n"
- + "list USER_ID\n"
- + "associate USER_ID PACKAGE MAC_ADDRESS\n"
- + "disassociate USER_ID PACKAGE MAC_ADDRESS";
-
- ShellCmd() {
- getContext().enforceCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_COMPANION_DEVICES, "ShellCmd");
- }
-
- @Override
- public int onCommand(String cmd) {
- try {
- switch (cmd) {
- case "list": {
- forEach(
- getAllAssociations(getNextArgInt()),
- a -> getOutPrintWriter()
- .println(a.getPackageName() + " "
- + a.getDeviceMacAddress()));
- }
- break;
-
- case "associate": {
- int userId = getNextArgInt();
- String pkg = getNextArgRequired();
- String address = getNextArgRequired();
- addAssociation(new Association(userId, address, pkg, null, false,
- System.currentTimeMillis()), userId);
- }
- break;
-
- case "disassociate": {
- removeAssociation(getNextArgInt(), getNextArgRequired(),
- getNextArgRequired());
- }
- break;
-
- case "simulate_connect": {
- onDeviceConnected(getNextArgRequired());
- }
- break;
-
- case "simulate_disconnect": {
- onDeviceDisconnected(getNextArgRequired());
- }
- break;
-
- default:
- return handleDefaultCommands(cmd);
- }
- return 0;
- } catch (Throwable t) {
- Slog.e(LOG_TAG, "Error running a command: $ " + cmd, t);
- getErrPrintWriter().println(Log.getStackTraceString(t));
- return 1;
- }
- }
-
- private int getNextArgInt() {
- return Integer.parseInt(getNextArgRequired());
- }
-
- @Override
- public void onHelp() {
- getOutPrintWriter().println(USAGE);
- }
+ static int getLastAssociationIdForUser(@UserIdInt int userId) {
+ return (userId + 1) * ASSOCIATIONS_IDS_PER_USER_RANGE;
}
-
private class BluetoothDeviceConnectedListener
extends BluetoothAdapter.BluetoothConnectionCallback {
@Override
@@ -1563,4 +1486,15 @@
CompanionDeviceManagerService.this.onDeviceDisconnected(device.getAddress());
}
}
+
+ private static @NonNull <T> Set<T> filterOut(
+ @NonNull Set<T> set, @NonNull Predicate<? super T> predicate) {
+ return CollectionUtils.filter(set, predicate.negate());
+ }
+
+ private Map<String, Set<Integer>> deepCopy(Map<String, Set<Integer>> orig) {
+ final Map<String, Set<Integer>> copy = new HashMap<>(orig.size(), 1f);
+ forEach(orig, (key, value) -> copy.put(key, new ArraySet<>(value)));
+ return copy;
+ }
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
new file mode 100644
index 0000000..e143f5e
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
@@ -0,0 +1,99 @@
+/*
+ * 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.server.companion;
+
+import static com.android.internal.util.CollectionUtils.forEach;
+import static com.android.server.companion.CompanionDeviceManagerService.LOG_TAG;
+
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+
+class CompanionDeviceShellCommand extends android.os.ShellCommand {
+ private final CompanionDeviceManagerService mService;
+
+ CompanionDeviceShellCommand(CompanionDeviceManagerService service) {
+ mService = service;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ try {
+ switch (cmd) {
+ case "list": {
+ forEach(
+ mService.getAllAssociations(getNextArgInt()),
+ a -> getOutPrintWriter()
+ .println(a.getPackageName() + " "
+ + a.getDeviceMacAddress()));
+ }
+ break;
+
+ case "associate": {
+ int userId = getNextArgInt();
+ String packageName = getNextArgRequired();
+ String address = getNextArgRequired();
+ mService.createAssociationInternal(userId, address, packageName, null);
+ }
+ break;
+
+ case "disassociate": {
+ mService.removeAssociation(getNextArgInt(), getNextArgRequired(),
+ getNextArgRequired());
+ }
+ break;
+
+ case "simulate_connect": {
+ mService.onDeviceConnected(getNextArgRequired());
+ }
+ break;
+
+ case "simulate_disconnect": {
+ mService.onDeviceDisconnected(getNextArgRequired());
+ }
+ break;
+
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ return 0;
+ } catch (Throwable t) {
+ Slog.e(LOG_TAG, "Error running a command: $ " + cmd, t);
+ getErrPrintWriter().println(Log.getStackTraceString(t));
+ return 1;
+ }
+ }
+
+ private int getNextArgInt() {
+ return Integer.parseInt(getNextArgRequired());
+ }
+
+ @Override
+ public void onHelp() {
+ PrintWriter pw = getOutPrintWriter();
+ pw.println("Companion Device Manager (companiondevice) commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.println(" list USER_ID");
+ pw.println(" List all Associations for a user.");
+ pw.println(" associate USER_ID PACKAGE MAC_ADDRESS");
+ pw.println(" Create a new Association.");
+ pw.println(" disassociate USER_ID PACKAGE MAC_ADDRESS");
+ pw.println(" Remove an existing Association.");
+ }
+}
diff --git a/services/companion/java/com/android/server/companion/PersistentDataStore.java b/services/companion/java/com/android/server/companion/PersistentDataStore.java
new file mode 100644
index 0000000..73d45ad
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/PersistentDataStore.java
@@ -0,0 +1,512 @@
+/*
+ * 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.server.companion;
+
+import static android.companion.DeviceId.TYPE_MAC_ADDRESS;
+
+import static com.android.internal.util.CollectionUtils.forEach;
+import static com.android.internal.util.XmlUtils.readBooleanAttribute;
+import static com.android.internal.util.XmlUtils.readIntAttribute;
+import static com.android.internal.util.XmlUtils.readLongAttribute;
+import static com.android.internal.util.XmlUtils.readStringAttribute;
+import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
+import static com.android.internal.util.XmlUtils.writeIntAttribute;
+import static com.android.internal.util.XmlUtils.writeLongAttribute;
+import static com.android.internal.util.XmlUtils.writeStringAttribute;
+
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.companion.Association;
+import android.companion.DeviceId;
+import android.os.Environment;
+import android.util.AtomicFile;
+import android.util.ExceptionUtils;
+import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
+
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * The class responsible for persisting Association records and other related information (such as
+ * previously used IDs) to a disk, and reading the data back from the disk.
+ *
+ * Before Android T the data was stored to `companion_device_manager_associations.xml` file in
+ * {@link Environment#getUserSystemDirectory(int)}
+ * (eg. `/data/system/users/0/companion_device_manager_associations.xml`)
+ * @see #getBaseLegacyStorageFileForUser(int)
+ *
+ * Before Android T the data was stored using the v0 schema.
+ *
+ * @see #readAssociationsV0(TypedXmlPullParser, int, Set)
+ * @see #readAssociationV0(TypedXmlPullParser, int, int, Set)
+ *
+ * The following snippet is a sample of a the file that is using v0 schema.
+ * <pre>{@code
+ * <associations>
+ * <association
+ * package="com.sample.companion.app"
+ * device="AA:BB:CC:DD:EE:00"
+ * time_approved="1634389553216" />
+ * <association
+ * package="com.another.sample.companion.app"
+ * device="AA:BB:CC:DD:EE:01"
+ * profile="android.app.role.COMPANION_DEVICE_WATCH"
+ * notify_device_nearby="false"
+ * time_approved="1634389752662" />
+ * </associations>
+ * }</pre>
+ *
+ *
+ * Since Android T the data is stored to `companion_device_manager.xml` file in
+ * {@link Environment#getDataSystemDeDirectory(int)}.
+ * (eg. `/data/system_de/0/companion_device_manager.xml`)
+ * @see #getBaseStorageFileForUser(int)
+
+ * Since Android T the data is stored using the v1 schema.
+ * In the v1 schema, a list of the previously used IDs is storead along with the association
+ * records.
+ * In the v1 schema, we no longer store MAC addresses, instead each assocition record may have a
+ * number of DeviceIds.
+ *
+ * @see #CURRENT_PERSISTENCE_VERSION
+ * @see #readAssociationsV1(TypedXmlPullParser, int, Set)
+ * @see #readAssociationV1(TypedXmlPullParser, int, Set)
+ * @see #readPreviouslyUsedIdsV1(TypedXmlPullParser, Map)
+ *
+ * The following snippet is a sample of a the file that is using v0 schema.
+ * <pre>{@code
+ * <state persistence-version="1">
+ * <associations>
+ * <association
+ * id="1"
+ * package="com.sample.companion.app"
+ * managed_by_app="false"
+ * notify_device_nearby="false"
+ * time_approved="1634389553216">
+ * <device-id type="mac_address" value="AA:BB:CC:DD:EE:00" />
+ * </association>
+ *
+ * <association
+ * id="3"
+ * profile="android.app.role.COMPANION_DEVICE_WATCH"
+ * package="com.sample.companion.another.app"
+ * managed_by_app="false"
+ * notify_device_nearby="false"
+ * time_approved="1634641160229">
+ * <device-id type="mac_address" value="AA:BB:CC:DD:EE:FF" />
+ * </association>
+ * </associations>
+ *
+ * <previously-used-ids>
+ * <package package_name="com.sample.companion.app">
+ * <id>2</id>
+ * </package>
+ * </previously-used-ids>
+ * </state>
+ * }</pre>
+ */
+final class PersistentDataStore {
+ private static final String LOG_TAG = CompanionDeviceManagerService.LOG_TAG + ".DataStore";
+ private static final boolean DEBUG = CompanionDeviceManagerService.DEBUG;
+
+ private static final int CURRENT_PERSISTENCE_VERSION = 1;
+
+ private static final String FILE_NAME_LEGACY = "companion_device_manager_associations.xml";
+ private static final String FILE_NAME = "companion_device_manager.xml";
+
+ private static final String XML_TAG_STATE = "state";
+ private static final String XML_TAG_ASSOCIATIONS = "associations";
+ private static final String XML_TAG_ASSOCIATION = "association";
+ private static final String XML_TAG_DEVICE_ID = "device-id";
+ private static final String XML_TAG_PREVIOUSLY_USED_IDS = "previously-used-ids";
+ private static final String XML_TAG_PACKAGE = "package";
+ private static final String XML_TAG_ID = "id";
+
+ private static final String XML_ATTR_PERSISTENCE_VERSION = "persistence-version";
+ private static final String XML_ATTR_ID = "id";
+ // Used in <package> elements, nested within <previously-used-ids> elements.
+ private static final String XML_ATTR_PACKAGE_NAME = "package_name";
+ // Used in <association> elements, nested within <associations> elements.
+ private static final String XML_ATTR_PACKAGE = "package";
+ private static final String XML_ATTR_DEVICE = "device";
+ private static final String XML_ATTR_PROFILE = "profile";
+ private static final String XML_ATTR_MANAGED_BY_APP = "managed_by_app";
+ private static final String XML_ATTR_NOTIFY_DEVICE_NEARBY = "notify_device_nearby";
+ private static final String XML_ATTR_TIME_APPROVED = "time_approved";
+ private static final String XML_ATTR_TYPE = "type";
+ private static final String XML_ATTR_VALUE = "value";
+
+ private final @NonNull ConcurrentMap<Integer, AtomicFile> mUserIdToStorageFile =
+ new ConcurrentHashMap<>();
+
+ /**
+ * Reads previously persisted data for the given user "into" the provided containers.
+ *
+ * @param userId Android UserID
+ * @param associationsOut a container to read the {@link Association}s "into".
+ * @param previouslyUsedIdsPerPackageOut a container to read the used IDs "into".
+ */
+ void readStateForUser(@UserIdInt int userId,
+ @NonNull Set<Association> associationsOut,
+ @NonNull Map<String, Set<Integer>> previouslyUsedIdsPerPackageOut) {
+ Slog.i(LOG_TAG, "Reading associations for user " + userId + " from disk");
+ final AtomicFile file = getStorageFileForUser(userId);
+ if (DEBUG) Slog.d(LOG_TAG, " > File=" + file.getBaseFile().getPath());
+
+ synchronized (file) {
+ File legacyBaseFile = null;
+ final AtomicFile readFrom;
+ final String rootTag;
+ if (!file.getBaseFile().exists()) {
+ if (DEBUG) Slog.d(LOG_TAG, " > File does not exist -> Try to read legacy file");
+
+ legacyBaseFile = getBaseLegacyStorageFileForUser(userId);
+ if (DEBUG) Slog.d(LOG_TAG, " > Legacy file=" + legacyBaseFile.getPath());
+ if (!legacyBaseFile.exists()) {
+ if (DEBUG) Slog.d(LOG_TAG, " > Legacy file does not exist -> Abort");
+ return;
+ }
+
+ readFrom = new AtomicFile(legacyBaseFile);
+ rootTag = XML_TAG_ASSOCIATIONS;
+ } else {
+ readFrom = file;
+ rootTag = XML_TAG_STATE;
+ }
+
+ if (DEBUG) Slog.d(LOG_TAG, " > Reading associations...");
+ final int version = readStateFromFileLocked(userId, readFrom, rootTag,
+ associationsOut, previouslyUsedIdsPerPackageOut);
+ if (DEBUG) {
+ Slog.d(LOG_TAG, " > Done reading: " + associationsOut);
+ if (version < CURRENT_PERSISTENCE_VERSION) {
+ Slog.d(LOG_TAG, " > File used old format: v." + version + " -> Re-write");
+ }
+ }
+
+ if (legacyBaseFile != null || version < CURRENT_PERSISTENCE_VERSION) {
+ // The data is either in the legacy file or in the legacy format, or both.
+ // Save the data to right file in using the current format.
+ if (DEBUG) {
+ Slog.d(LOG_TAG, " > Writing the data to " + file.getBaseFile().getPath());
+ }
+ persistStateToFileLocked(file, associationsOut, previouslyUsedIdsPerPackageOut);
+
+ if (legacyBaseFile != null) {
+ // We saved the data to the right file, can delete the old file now.
+ if (DEBUG) Slog.d(LOG_TAG, " > Deleting legacy file");
+ legacyBaseFile.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Persisted data to the disk.
+ *
+ * @param userId Android UserID
+ * @param associations a set of user's associations.
+ * @param previouslyUsedIdsPerPackage a set previously used Association IDs for the user.
+ */
+ void persistStateForUser(@UserIdInt int userId, @NonNull Set<Association> associations,
+ @NonNull Map<String, Set<Integer>> previouslyUsedIdsPerPackage) {
+ Slog.i(LOG_TAG, "Writing associations for user " + userId + " to disk");
+ if (DEBUG) Slog.d(LOG_TAG, " > " + associations);
+
+ final AtomicFile file = getStorageFileForUser(userId);
+ if (DEBUG) Slog.d(LOG_TAG, " > File=" + file.getBaseFile().getPath());
+ synchronized (file) {
+ persistStateToFileLocked(file, associations, previouslyUsedIdsPerPackage);
+ }
+ }
+
+ private int readStateFromFileLocked(@UserIdInt int userId, @NonNull AtomicFile file,
+ @NonNull String rootTag, @Nullable Set<Association> associationsOut,
+ @NonNull Map<String, Set<Integer>> previouslyUsedIdsPerPackageOut) {
+ try (FileInputStream in = file.openRead()) {
+ final TypedXmlPullParser parser = Xml.resolvePullParser(in);
+
+ XmlUtils.beginDocument(parser, rootTag);
+ final int version = readIntAttribute(parser, XML_ATTR_PERSISTENCE_VERSION, 0);
+ switch (version) {
+ case 0:
+ readAssociationsV0(parser, userId, associationsOut);
+ break;
+ case 1:
+ while (true) {
+ parser.nextTag();
+ if (isStartOfTag(parser, XML_TAG_ASSOCIATIONS)) {
+ readAssociationsV1(parser, userId, associationsOut);
+ } else if (isStartOfTag(parser, XML_TAG_PREVIOUSLY_USED_IDS)) {
+ readPreviouslyUsedIdsV1(parser, previouslyUsedIdsPerPackageOut);
+ } else if (isEndOfTag(parser, rootTag)) {
+ break;
+ }
+ }
+ break;
+ }
+ return version;
+ } catch (XmlPullParserException | IOException e) {
+ Slog.e(LOG_TAG, "Error while reading associations file", e);
+ return -1;
+ }
+ }
+
+ private void persistStateToFileLocked(@NonNull AtomicFile file,
+ @Nullable Set<Association> associations,
+ @NonNull Map<String, Set<Integer>> previouslyUsedIdsPerPackage) {
+ file.write(out -> {
+ try {
+ final TypedXmlSerializer serializer = Xml.resolveSerializer(out);
+ serializer.setFeature(
+ "http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+ serializer.startDocument(null, true);
+ serializer.startTag(null, XML_TAG_STATE);
+ writeIntAttribute(serializer,
+ XML_ATTR_PERSISTENCE_VERSION, CURRENT_PERSISTENCE_VERSION);
+
+ writeAssociations(serializer, associations);
+ writePreviouslyUsedIds(serializer, previouslyUsedIdsPerPackage);
+
+ serializer.endTag(null, XML_TAG_STATE);
+ serializer.endDocument();
+ } catch (Exception e) {
+ Slog.e(LOG_TAG, "Error while writing associations file", e);
+ throw ExceptionUtils.propagate(e);
+ }
+ });
+ }
+
+ private @NonNull AtomicFile getStorageFileForUser(@UserIdInt int userId) {
+ return mUserIdToStorageFile.computeIfAbsent(userId,
+ u -> new AtomicFile(getBaseStorageFileForUser(userId)));
+ }
+
+ private static @NonNull File getBaseStorageFileForUser(@UserIdInt int userId) {
+ return new File(Environment.getDataSystemDeDirectory(userId), FILE_NAME);
+ }
+
+ private static @NonNull File getBaseLegacyStorageFileForUser(@UserIdInt int userId) {
+ return new File(Environment.getUserSystemDirectory(userId), FILE_NAME_LEGACY);
+ }
+
+ private static void readAssociationsV0(@NonNull TypedXmlPullParser parser,
+ @UserIdInt int userId, @NonNull Set<Association> out)
+ throws XmlPullParserException, IOException {
+ requireStartOfTag(parser, XML_TAG_ASSOCIATIONS);
+
+ // Before Android T Associations didn't have IDs, so when we are upgrading from S (reading
+ // from V0) we need to generate and assign IDs to the existing Associations.
+ // It's safe to do it here, because CDM cannot create new Associations before it reads
+ // existing ones from the backup files. And the fact that we are reading from a V0 file,
+ // means that CDM hasn't assigned any IDs yet, so we can just start from the first available
+ // id for each user (eg. 1 for user 0; 100 001 - for user 1; 200 001 - for user 2; etc).
+ int associationId = CompanionDeviceManagerService.getFirstAssociationIdForUser(userId);
+ while (true) {
+ parser.nextTag();
+ if (isEndOfTag(parser, XML_TAG_ASSOCIATIONS)) break;
+ if (!isStartOfTag(parser, XML_TAG_ASSOCIATION)) continue;
+
+ readAssociationV0(parser, userId, associationId++, out);
+ }
+ }
+
+ private static void readAssociationV0(@NonNull TypedXmlPullParser parser, @UserIdInt int userId,
+ int associationId, @NonNull Set<Association> out) throws XmlPullParserException {
+ requireStartOfTag(parser, XML_TAG_ASSOCIATION);
+
+ final String appPackage = readStringAttribute(parser, XML_ATTR_PACKAGE);
+ // In v0, CDM did not have a notion of a DeviceId yet, instead each Association had a MAC
+ // address.
+ final String deviceAddress = readStringAttribute(parser, XML_ATTR_DEVICE);
+
+ if (appPackage == null || deviceAddress == null) return;
+
+ final String profile = readStringAttribute(parser, XML_ATTR_PROFILE);
+ final boolean notify = readBooleanAttribute(parser, XML_ATTR_NOTIFY_DEVICE_NEARBY);
+ final long timeApproved = readLongAttribute(parser, XML_ATTR_TIME_APPROVED, 0L);
+
+ // "Convert" MAC address into a DeviceId.
+ final List<DeviceId> deviceIds = Arrays.asList(
+ new DeviceId(TYPE_MAC_ADDRESS, deviceAddress));
+ out.add(new Association(associationId, userId, appPackage, deviceIds, profile,
+ /* managedByCompanionApp */false, notify, timeApproved));
+ }
+
+ private static void readAssociationsV1(@NonNull TypedXmlPullParser parser,
+ @UserIdInt int userId, @NonNull Set<Association> out)
+ throws XmlPullParserException, IOException {
+ requireStartOfTag(parser, XML_TAG_ASSOCIATIONS);
+
+ while (true) {
+ parser.nextTag();
+ if (isEndOfTag(parser, XML_TAG_ASSOCIATIONS)) break;
+ if (!isStartOfTag(parser, XML_TAG_ASSOCIATION)) continue;
+
+ readAssociationV1(parser, userId, out);
+ }
+ }
+
+ private static void readAssociationV1(@NonNull TypedXmlPullParser parser, @UserIdInt int userId,
+ @NonNull Set<Association> out) throws XmlPullParserException, IOException {
+ requireStartOfTag(parser, XML_TAG_ASSOCIATION);
+
+ final int associationId = readIntAttribute(parser, XML_ATTR_ID);
+ final String profile = readStringAttribute(parser, XML_ATTR_PROFILE);
+ final String appPackage = readStringAttribute(parser, XML_ATTR_PACKAGE);
+ final boolean managedByApp = readBooleanAttribute(parser, XML_ATTR_MANAGED_BY_APP);
+ final boolean notify = readBooleanAttribute(parser, XML_ATTR_NOTIFY_DEVICE_NEARBY);
+ final long timeApproved = readLongAttribute(parser, XML_ATTR_TIME_APPROVED, 0L);
+
+ final List<DeviceId> deviceIds = new ArrayList<>();
+ while (true) {
+ parser.nextTag();
+ if (isEndOfTag(parser, XML_TAG_ASSOCIATION)) break;
+ if (!isStartOfTag(parser, XML_TAG_DEVICE_ID)) continue;
+
+ final String type = readStringAttribute(parser, XML_ATTR_TYPE);
+ final String value = readStringAttribute(parser, XML_ATTR_VALUE);
+ deviceIds.add(new DeviceId(type, value));
+ }
+
+ out.add(new Association(associationId, userId, appPackage, deviceIds, profile, managedByApp,
+ notify, timeApproved));
+ }
+
+ private static void readPreviouslyUsedIdsV1(@NonNull TypedXmlPullParser parser,
+ @NonNull Map<String, Set<Integer>> out) throws XmlPullParserException, IOException {
+ requireStartOfTag(parser, XML_TAG_PREVIOUSLY_USED_IDS);
+
+ while (true) {
+ parser.nextTag();
+ if (isEndOfTag(parser, XML_TAG_PREVIOUSLY_USED_IDS)) break;
+ if (!isStartOfTag(parser, XML_TAG_PACKAGE)) continue;
+
+ final String packageName = readStringAttribute(parser, XML_ATTR_PACKAGE_NAME);
+ final Set<Integer> usedIds = new HashSet<>();
+
+ while (true) {
+ parser.nextTag();
+ if (isEndOfTag(parser, XML_TAG_PACKAGE)) break;
+ if (!isStartOfTag(parser, XML_TAG_ID)) continue;
+
+ parser.nextToken();
+ final int id = Integer.parseInt(parser.getText());
+ usedIds.add(id);
+ }
+
+ out.put(packageName, usedIds);
+ }
+ }
+
+ private static void writeAssociations(@NonNull XmlSerializer parent,
+ @Nullable Set<Association> associations) throws IOException {
+ final XmlSerializer serializer = parent.startTag(null, XML_TAG_ASSOCIATIONS);
+ forEach(associations, it -> writeAssociation(serializer, it));
+ serializer.endTag(null, XML_TAG_ASSOCIATIONS);
+ }
+
+ private static void writeAssociation(@NonNull XmlSerializer parent, @NonNull Association a)
+ throws IOException {
+ final XmlSerializer serializer = parent.startTag(null, XML_TAG_ASSOCIATION);
+
+ writeIntAttribute(serializer, XML_ATTR_ID, a.getAssociationId());
+ writeStringAttribute(serializer, XML_ATTR_PROFILE, a.getDeviceProfile());
+ writeStringAttribute(serializer, XML_ATTR_PACKAGE, a.getPackageName());
+ writeBooleanAttribute(serializer, XML_ATTR_MANAGED_BY_APP, a.isManagedByCompanionApp());
+ writeBooleanAttribute(
+ serializer, XML_ATTR_NOTIFY_DEVICE_NEARBY, a.isNotifyOnDeviceNearby());
+ writeLongAttribute(serializer, XML_ATTR_TIME_APPROVED, a.getTimeApprovedMs());
+
+ final List<DeviceId> deviceIds = a.getDeviceIds();
+ for (int i = 0, size = deviceIds.size(); i < size; i++) {
+ writeDeviceId(serializer, deviceIds.get(i));
+ }
+
+ serializer.endTag(null, XML_TAG_ASSOCIATION);
+ }
+
+ private static void writeDeviceId(@NonNull XmlSerializer parent, @NonNull DeviceId deviceId)
+ throws IOException {
+ final XmlSerializer serializer = parent.startTag(null, XML_TAG_DEVICE_ID);
+
+ writeStringAttribute(serializer, XML_ATTR_TYPE, deviceId.getType());
+ writeStringAttribute(serializer, XML_ATTR_VALUE, deviceId.getValue());
+
+ serializer.endTag(null, XML_TAG_DEVICE_ID);
+ }
+
+ private static void writePreviouslyUsedIds(@NonNull XmlSerializer parent,
+ @NonNull Map<String, Set<Integer>> previouslyUsedIdsPerPackage) throws IOException {
+ final XmlSerializer serializer = parent.startTag(null, XML_TAG_PREVIOUSLY_USED_IDS);
+ for (Map.Entry<String, Set<Integer>> entry : previouslyUsedIdsPerPackage.entrySet()) {
+ writePreviouslyUsedIdsForPackage(serializer, entry.getKey(), entry.getValue());
+ }
+ serializer.endTag(null, XML_TAG_PREVIOUSLY_USED_IDS);
+ }
+
+ private static void writePreviouslyUsedIdsForPackage(@NonNull XmlSerializer parent,
+ @NonNull String packageName, @NonNull Set<Integer> previouslyUsedIds)
+ throws IOException {
+ final XmlSerializer serializer = parent.startTag(null, XML_TAG_PACKAGE);
+ writeStringAttribute(serializer, XML_ATTR_PACKAGE_NAME, packageName);
+ forEach(previouslyUsedIds, id -> serializer.startTag(null, XML_TAG_ID)
+ .text(Integer.toString(id))
+ .endTag(null, XML_TAG_ID));
+ serializer.endTag(null, XML_TAG_PACKAGE);
+ }
+
+ private static boolean isStartOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
+ throws XmlPullParserException {
+ return parser.getEventType() == START_TAG && tag.equals(parser.getName());
+ }
+
+ private static boolean isEndOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
+ throws XmlPullParserException {
+ return parser.getEventType() == END_TAG && tag.equals(parser.getName());
+ }
+
+ private static void requireStartOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
+ throws XmlPullParserException {
+ if (isStartOfTag(parser, tag)) return;
+ throw new XmlPullParserException(
+ "Should be at the start of \"" + XML_TAG_ASSOCIATIONS + "\" tag");
+ }
+}
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 95dc667..b641377 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -16,6 +16,9 @@
# ServiceWatcher
per-file ServiceWatcher.java = sooniln@google.com
+# Health
+per-file BatteryService.java = file:platform/hardware/interfaces:/health/aidl/OWNERS
+
per-file *Alarm* = file:/apex/jobscheduler/OWNERS
per-file *AppOp* = file:/core/java/android/permission/OWNERS
per-file *Battery* = file:/BATTERY_STATS_OWNERS
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index e7b078a..0fde6fa 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -45,8 +45,8 @@
import com.android.internal.os.ZygoteConnectionConstants;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.am.ActivityManagerService;
-import com.android.server.am.CriticalEventLog;
import com.android.server.am.TraceErrorLogger;
+import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.wm.SurfaceAnimationThread;
import java.io.BufferedReader;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index fe9244f..f6c1106 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -382,6 +382,7 @@
import com.android.server.appop.AppOpsService;
import com.android.server.compat.PlatformCompat;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
+import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.firewall.IntentFirewall;
import com.android.server.graphics.fonts.FontManagerInternal;
import com.android.server.job.JobSchedulerInternal;
diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
index 5fac879..b7ea3dc 100644
--- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
@@ -49,6 +49,7 @@
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.MemoryPressureUtil;
+import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.wm.WindowProcessController;
import java.io.File;
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 565c9ae..243a336b 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1270,6 +1270,9 @@
capsBuilder.addCapability(NET_CAPABILITY_NOT_METERED);
}
+ capsBuilder.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
+ ? Arrays.asList(mConfig.underlyingNetworks) : null);
+
mNetworkCapabilities = capsBuilder.build();
mNetworkAgent = new NetworkAgent(mContext, mLooper, NETWORKTYPE /* logtag */,
mNetworkCapabilities, lp,
@@ -1290,8 +1293,6 @@
} finally {
Binder.restoreCallingIdentity(token);
}
- mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
- ? Arrays.asList(mConfig.underlyingNetworks) : null);
updateState(DetailedState.CONNECTED, "agentConnect");
}
diff --git a/services/core/java/com/android/server/am/CriticalEventLog.java b/services/core/java/com/android/server/criticalevents/CriticalEventLog.java
similarity index 96%
rename from services/core/java/com/android/server/am/CriticalEventLog.java
rename to services/core/java/com/android/server/criticalevents/CriticalEventLog.java
index 6b69559..d5fe9c9 100644
--- a/services/core/java/com/android/server/am/CriticalEventLog.java
+++ b/services/core/java/com/android/server/criticalevents/CriticalEventLog.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.am;
+package com.android.server.criticalevents;
import android.os.Handler;
import android.os.HandlerThread;
@@ -23,11 +23,11 @@
import com.android.framework.protobuf.nano.MessageNanoPrinter;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.RingBuffer;
-import com.android.server.am.nano.CriticalEventLogProto;
-import com.android.server.am.nano.CriticalEventLogStorageProto;
-import com.android.server.am.nano.CriticalEventProto;
-import com.android.server.am.nano.CriticalEventProto.HalfWatchdog;
-import com.android.server.am.nano.CriticalEventProto.Watchdog;
+import com.android.server.criticalevents.nano.CriticalEventLogProto;
+import com.android.server.criticalevents.nano.CriticalEventLogStorageProto;
+import com.android.server.criticalevents.nano.CriticalEventProto;
+import com.android.server.criticalevents.nano.CriticalEventProto.HalfWatchdog;
+import com.android.server.criticalevents.nano.CriticalEventProto.Watchdog;
import java.io.File;
import java.io.FileOutputStream;
diff --git a/services/core/java/com/android/server/locales/LocaleManagerService.java b/services/core/java/com/android/server/locales/LocaleManagerService.java
index 0045499..ffeaad1 100644
--- a/services/core/java/com/android/server/locales/LocaleManagerService.java
+++ b/services/core/java/com/android/server/locales/LocaleManagerService.java
@@ -18,11 +18,14 @@
import static java.util.Objects.requireNonNull;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
import android.app.ILocaleManager;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.LocaleList;
@@ -142,7 +145,6 @@
}
}
-
private void setApplicationLocalesUnchecked(@NonNull String appPackageName,
@UserIdInt int userId, @NonNull LocaleList locales) {
if (DEBUG) {
@@ -152,9 +154,76 @@
final ActivityTaskManagerInternal.PackageConfigurationUpdater updater =
mActivityTaskManagerInternal.createPackageConfigurationUpdater(appPackageName,
userId);
- updater.setLocales(locales).commit();
+ boolean isSuccess = updater.setLocales(locales).commit();
+
+ //We want to send the broadcasts only if config was actually updated on commit.
+ if (isSuccess) {
+ notifyAppWhoseLocaleChanged(appPackageName, userId, locales);
+ notifyInstallerOfAppWhoseLocaleChanged(appPackageName, userId, locales);
+ notifyRegisteredReceivers(appPackageName, userId, locales);
+ }
}
+ /**
+ * Sends an implicit broadcast with action
+ * {@link android.content.Intent#ACTION_APPLICATION_LOCALE_CHANGED}
+ * to receivers with {@link android.Manifest.permission#READ_APP_SPECIFIC_LOCALES}.
+ */
+ private void notifyRegisteredReceivers(String appPackageName, int userId,
+ LocaleList locales) {
+ Intent intent = createBaseIntent(Intent.ACTION_APPLICATION_LOCALE_CHANGED,
+ appPackageName, locales);
+ mContext.sendBroadcastAsUser(intent, UserHandle.of(userId),
+ Manifest.permission.READ_APP_SPECIFIC_LOCALES);
+ }
+
+ /**
+ * Sends an explicit broadcast with action
+ * {@link android.content.Intent#ACTION_APPLICATION_LOCALE_CHANGED} to
+ * the installer (as per {@link android.content.pm.InstallSourceInfo#getInstallingPackageName})
+ * of app whose locale has changed.
+ *
+ * <p><b>Note:</b> This is can be used by installers to deal with cases such as
+ * language-based APK Splits.
+ */
+ private void notifyInstallerOfAppWhoseLocaleChanged(String appPackageName, int userId,
+ LocaleList locales) {
+ try {
+ String installingPackageName = mContext.getPackageManager()
+ .getInstallSourceInfo(appPackageName).getInstallingPackageName();
+ if (installingPackageName != null) {
+ Intent intent = createBaseIntent(Intent.ACTION_APPLICATION_LOCALE_CHANGED,
+ appPackageName, locales);
+ //Set package name to ensure that only installer of the app receives this intent.
+ intent.setPackage(installingPackageName);
+ mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Package not found " + appPackageName);
+ }
+ }
+
+ /**
+ * Sends an explicit broadcast with action {@link android.content.Intent#ACTION_LOCALE_CHANGED}
+ * to the app whose locale has changed.
+ */
+ private void notifyAppWhoseLocaleChanged(String appPackageName, int userId,
+ LocaleList locales) {
+ Intent intent = createBaseIntent(Intent.ACTION_LOCALE_CHANGED, appPackageName, locales);
+ //Set package name to ensure that only the app whose locale changed receives this intent.
+ intent.setPackage(appPackageName);
+ intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+ mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
+ }
+
+ private static Intent createBaseIntent(String intentAction, String appPackageName,
+ LocaleList locales) {
+ return new Intent(intentAction)
+ .putExtra(Intent.EXTRA_PACKAGE_NAME, appPackageName)
+ .putExtra(Intent.EXTRA_LOCALE_LIST, locales)
+ .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+ | Intent.FLAG_RECEIVER_FOREGROUND);
+ }
/**
* Checks if the package is owned by the calling app or not for the given user id.
@@ -175,7 +244,7 @@
}
private void enforceChangeConfigurationPermission() {
- mContext.enforceCallingPermission(
+ mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_CONFIGURATION, "setApplicationLocales");
}
@@ -231,7 +300,7 @@
}
private void enforceReadAppSpecificLocalesPermission() {
- mContext.enforceCallingPermission(
+ mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_APP_SPECIFIC_LOCALES,
"getApplicationLocales");
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b880a61..f14f7695 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -479,6 +479,7 @@
private ActivityManagerInternal mAmi;
private IPackageManager mPackageManager;
private PackageManager mPackageManagerClient;
+ private PackageManagerInternal mPackageManagerInternal;
AudioManager mAudioManager;
AudioManagerInternal mAudioManagerInternal;
// Can be null for wear
@@ -2212,6 +2213,7 @@
mUgmInternal = ugmInternal;
mPackageManager = packageManager;
mPackageManagerClient = packageManagerClient;
+ mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mAppOps = appOps;
mAppOpsService = iAppOps;
try {
@@ -2292,10 +2294,12 @@
});
}
});
+ mPermissionHelper = permissionHelper;
mPreferencesHelper = new PreferencesHelper(getContext(),
mPackageManagerClient,
mRankingHandler,
mZenModeHelper,
+ mPermissionHelper,
new NotificationChannelLoggerImpl(),
mAppOps,
new SysUiStatsEvent.BuilderFactory());
@@ -2309,7 +2313,6 @@
mGroupHelper = groupHelper;
mVibratorHelper = new VibratorHelper(getContext());
mHistoryManager = historyManager;
- mPermissionHelper = permissionHelper;
// This is a ManagedServices object that keeps track of the listeners.
mListeners = notificationListeners;
@@ -3481,7 +3484,7 @@
mPreferencesHelper.setEnabled(pkg, uid, enabled);
// TODO (b/194833441): this is being ignored by app ops now that the permission
- // exists
+ // exists, so send the broadcast manually
mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg,
enabled ? MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
@@ -3541,11 +3544,7 @@
"canNotifyAsPackage for uid " + uid);
}
- if (mEnableAppSettingMigration) {
- return mPermissionHelper.hasPermission(uid);
- } else {
- return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE;
- }
+ return areNotificationsEnabledForPackageInt(pkg, uid);
}
/**
@@ -4082,15 +4081,13 @@
}
@Override
- public int getAppsBypassingDndCount(int userId) {
- checkCallerIsSystem();
- return mPreferencesHelper.getAppsBypassingDndCount(userId);
- }
-
- @Override
public ParceledListSlice<NotificationChannel> getNotificationChannelsBypassingDnd(
String pkg, int userId) {
checkCallerIsSystem();
+ if (!areNotificationsEnabledForPackage(pkg,
+ mPackageManagerInternal.getPackageUid(pkg, 0, userId))) {
+ return ParceledListSlice.emptyList();
+ }
return mPreferencesHelper.getNotificationChannelsBypassingDnd(pkg, userId);
}
@@ -6731,13 +6728,30 @@
// blocked apps
- if (isBlocked(r, mUsageStats)) {
+ boolean isBlocked = !areNotificationsEnabledForPackageInt(pkg, uid);
+ synchronized (mNotificationLock) {
+ isBlocked |= isRecordBlockedLocked(r);
+ }
+ if (isBlocked) {
+ if (DBG) {
+ Slog.e(TAG, "Suppressing notification from package " + r.getSbn().getPackageName()
+ + " by user request.");
+ }
+ mUsageStats.registerBlocked(r);
return false;
}
return true;
}
+ private boolean areNotificationsEnabledForPackageInt(String pkg, int uid) {
+ if (mEnableAppSettingMigration) {
+ return mPermissionHelper.hasPermission(uid);
+ } else {
+ return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE;
+ }
+ }
+
protected int getNotificationCount(String pkg, int userId, int excludedId,
String excludedTag) {
int count = 0;
@@ -6766,24 +6780,15 @@
return count;
}
- protected boolean isBlocked(NotificationRecord r, NotificationUsageStats usageStats) {
- if (isBlocked(r)) {
- if (DBG) {
- Slog.e(TAG, "Suppressing notification from package " + r.getSbn().getPackageName()
- + " by user request.");
- }
- usageStats.registerBlocked(r);
- return true;
- }
- return false;
- }
-
- private boolean isBlocked(NotificationRecord r) {
+ /**
+ * Checks whether a notification is banned at a group or channel level or if the NAS or system
+ * has blocked the notification.
+ */
+ @GuardedBy("mNotificationLock")
+ boolean isRecordBlockedLocked(NotificationRecord r) {
final String pkg = r.getSbn().getPackageName();
final int callingUid = r.getSbn().getUid();
return mPreferencesHelper.isGroupBlocked(pkg, callingUid, r.getChannel().getGroup())
- || mPreferencesHelper.getImportance(pkg, callingUid)
- == NotificationManager.IMPORTANCE_NONE
|| r.getImportance() == NotificationManager.IMPORTANCE_NONE;
}
@@ -7094,6 +7099,9 @@
@Override
public void run() {
+ String pkg = StatusBarNotification.getPkgFromKey(key);
+ int uid = StatusBarNotification.getUidFromKey(key);
+ boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
synchronized (mNotificationLock) {
try {
NotificationRecord r = null;
@@ -7110,8 +7118,11 @@
return;
}
- if (isBlocked(r)) {
- Slog.i(TAG, "notification blocked by assistant request");
+ if (appBanned || isRecordBlockedLocked(r)) {
+ mUsageStats.registerBlocked(r);
+ if (DBG) {
+ Slog.e(TAG, "Suppressing notification from package " + pkg);
+ }
return;
}
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index 5e381ea..a3c009a 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -58,6 +58,10 @@
mMigrationEnabled = migrationEnabled;
}
+ public boolean isMigrationEnabled() {
+ return mMigrationEnabled;
+ }
+
/**
* Returns whether the given uid holds the notification permission. Must not be called
* with a lock held.
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 6cf7d06..b94721a 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -169,6 +169,7 @@
private final PackageManager mPm;
private final RankingHandler mRankingHandler;
private final ZenModeHelper mZenModeHelper;
+ private final PermissionHelper mPermissionHelper;
private final NotificationChannelLogger mNotificationChannelLogger;
private final AppOpsManager mAppOps;
@@ -187,12 +188,14 @@
private int mCurrentUserId = UserHandle.USER_NULL;
public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
- ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger,
+ ZenModeHelper zenHelper, PermissionHelper permHelper,
+ NotificationChannelLogger notificationChannelLogger,
AppOpsManager appOpsManager,
SysUiStatsEvent.BuilderFactory statsEventBuilderFactory) {
mContext = context;
mZenModeHelper = zenHelper;
mRankingHandler = rankingHandler;
+ mPermissionHelper = permHelper;
mPm = pm;
mNotificationChannelLogger = notificationChannelLogger;
mAppOps = appOpsManager;
@@ -791,6 +794,7 @@
Objects.requireNonNull(group);
Objects.requireNonNull(group.getId());
Objects.requireNonNull(!TextUtils.isEmpty(group.getName()));
+ boolean needsDndChange = false;
synchronized (mPackagePreferences) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
@@ -809,7 +813,7 @@
// but the system can
if (group.isBlocked() != oldGroup.isBlocked()) {
group.lockFields(NotificationChannelGroup.USER_LOCKED_BLOCKED_STATE);
- updateChannelsBypassingDnd();
+ needsDndChange = true;
}
}
}
@@ -822,6 +826,9 @@
}
r.groups.put(group.getId(), group);
}
+ if (needsDndChange) {
+ updateChannelsBypassingDnd();
+ }
}
@Override
@@ -831,7 +838,7 @@
Objects.requireNonNull(channel);
Objects.requireNonNull(channel.getId());
Preconditions.checkArgument(!TextUtils.isEmpty(channel.getName()));
- boolean needsPolicyFileChange = false, wasUndeleted = false;
+ boolean needsPolicyFileChange = false, wasUndeleted = false, needsDndChange = false;
synchronized (mPackagePreferences) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
@@ -897,7 +904,7 @@
if (bypassDnd != mAreChannelsBypassingDnd
|| previousExistingImportance != existing.getImportance()) {
- updateChannelsBypassingDnd();
+ needsDndChange = true;
}
}
}
@@ -912,60 +919,64 @@
mNotificationChannelLogger.logNotificationChannelModified(existing, uid, pkg,
previousLoggingImportance, false);
}
- return needsPolicyFileChange;
- }
-
- if (r.channels.size() >= NOTIFICATION_CHANNEL_COUNT_LIMIT) {
- throw new IllegalStateException("Limit exceed; cannot create more channels");
- }
-
- needsPolicyFileChange = true;
-
- if (channel.getImportance() < IMPORTANCE_NONE
- || channel.getImportance() > NotificationManager.IMPORTANCE_MAX) {
- throw new IllegalArgumentException("Invalid importance level");
- }
-
- // Reset fields that apps aren't allowed to set.
- if (fromTargetApp && !hasDndAccess) {
- channel.setBypassDnd(r.priority == Notification.PRIORITY_MAX);
- }
- if (fromTargetApp) {
- channel.setLockscreenVisibility(r.visibility);
- channel.setAllowBubbles(existing != null
- ? existing.getAllowBubbles()
- : NotificationChannel.DEFAULT_ALLOW_BUBBLE);
- }
- clearLockedFieldsLocked(channel);
- channel.setImportanceLockedByOEM(r.oemLockedImportance);
- if (!channel.isImportanceLockedByOEM()) {
- if (r.oemLockedChannels.contains(channel.getId())) {
- channel.setImportanceLockedByOEM(true);
+ } else {
+ if (r.channels.size() >= NOTIFICATION_CHANNEL_COUNT_LIMIT) {
+ throw new IllegalStateException("Limit exceed; cannot create more channels");
}
- }
- channel.setImportanceLockedByCriticalDeviceFunction(r.defaultAppLockedImportance);
- if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
- channel.setLockscreenVisibility(
- NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
- }
- if (!r.showBadge) {
- channel.setShowBadge(false);
- }
- channel.setOriginalImportance(channel.getImportance());
- // validate parent
- if (channel.getParentChannelId() != null) {
- Preconditions.checkArgument(r.channels.containsKey(channel.getParentChannelId()),
- "Tried to create a conversation channel without a preexisting parent");
- }
+ needsPolicyFileChange = true;
- r.channels.put(channel.getId(), channel);
- if (channel.canBypassDnd() != mAreChannelsBypassingDnd) {
- updateChannelsBypassingDnd();
+ if (channel.getImportance() < IMPORTANCE_NONE
+ || channel.getImportance() > NotificationManager.IMPORTANCE_MAX) {
+ throw new IllegalArgumentException("Invalid importance level");
+ }
+
+ // Reset fields that apps aren't allowed to set.
+ if (fromTargetApp && !hasDndAccess) {
+ channel.setBypassDnd(r.priority == Notification.PRIORITY_MAX);
+ }
+ if (fromTargetApp) {
+ channel.setLockscreenVisibility(r.visibility);
+ channel.setAllowBubbles(existing != null
+ ? existing.getAllowBubbles()
+ : NotificationChannel.DEFAULT_ALLOW_BUBBLE);
+ }
+ clearLockedFieldsLocked(channel);
+ channel.setImportanceLockedByOEM(r.oemLockedImportance);
+ if (!channel.isImportanceLockedByOEM()) {
+ if (r.oemLockedChannels.contains(channel.getId())) {
+ channel.setImportanceLockedByOEM(true);
+ }
+ }
+ channel.setImportanceLockedByCriticalDeviceFunction(r.defaultAppLockedImportance);
+ if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
+ channel.setLockscreenVisibility(
+ NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
+ }
+ if (!r.showBadge) {
+ channel.setShowBadge(false);
+ }
+ channel.setOriginalImportance(channel.getImportance());
+
+ // validate parent
+ if (channel.getParentChannelId() != null) {
+ Preconditions.checkArgument(
+ r.channels.containsKey(channel.getParentChannelId()),
+ "Tried to create a conversation channel without a preexisting parent");
+ }
+
+ r.channels.put(channel.getId(), channel);
+ if (channel.canBypassDnd() != mAreChannelsBypassingDnd) {
+ needsDndChange = true;
+ }
+ MetricsLogger.action(getChannelLog(channel, pkg).setType(
+ com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_OPEN));
+ mNotificationChannelLogger.logNotificationChannelCreated(channel, uid, pkg);
}
- MetricsLogger.action(getChannelLog(channel, pkg).setType(
- com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_OPEN));
- mNotificationChannelLogger.logNotificationChannelCreated(channel, uid, pkg);
+ }
+
+ if (needsDndChange) {
+ updateChannelsBypassingDnd();
}
return needsPolicyFileChange;
@@ -997,6 +1008,7 @@
boolean fromUser) {
Objects.requireNonNull(updatedChannel);
Objects.requireNonNull(updatedChannel.getId());
+ boolean needsDndChange = false;
synchronized (mPackagePreferences) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
@@ -1050,9 +1062,12 @@
if (updatedChannel.canBypassDnd() != mAreChannelsBypassingDnd
|| channel.getImportance() != updatedChannel.getImportance()) {
- updateChannelsBypassingDnd();
+ needsDndChange = true;
}
}
+ if (needsDndChange) {
+ updateChannelsBypassingDnd();
+ }
updateConfig();
}
@@ -1126,6 +1141,8 @@
@Override
public boolean deleteNotificationChannel(String pkg, int uid, String channelId) {
+ boolean deletedChannel = false;
+ boolean channelBypassedDnd = false;
synchronized (mPackagePreferences) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
@@ -1133,13 +1150,18 @@
}
NotificationChannel channel = r.channels.get(channelId);
if (channel != null) {
- return deleteNotificationChannelLocked(channel, pkg, uid);
+ channelBypassedDnd = channel.canBypassDnd();
+ deletedChannel = deleteNotificationChannelLocked(channel, pkg, uid);
}
- return false;
}
+ if (channelBypassedDnd) {
+ updateChannelsBypassingDnd();
+ }
+ return deletedChannel;
}
- private boolean deleteNotificationChannelLocked(NotificationChannel channel, String pkg, int uid) {
+ private boolean deleteNotificationChannelLocked(NotificationChannel channel, String pkg,
+ int uid) {
if (!channel.isDeleted()) {
channel.setDeleted(true);
channel.setDeletedTimeMs(System.currentTimeMillis());
@@ -1147,10 +1169,6 @@
lm.setType(com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_CLOSE);
MetricsLogger.action(lm);
mNotificationChannelLogger.logNotificationChannelDeleted(channel, uid, pkg);
-
- if (mAreChannelsBypassingDnd && channel.canBypassDnd()) {
- updateChannelsBypassingDnd();
- }
return true;
}
return false;
@@ -1352,6 +1370,7 @@
public List<NotificationChannel> deleteNotificationChannelGroup(String pkg, int uid,
String groupId) {
List<NotificationChannel> deletedChannels = new ArrayList<>();
+ boolean groupBypassedDnd = false;
synchronized (mPackagePreferences) {
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null || TextUtils.isEmpty(groupId)) {
@@ -1368,11 +1387,15 @@
for (int i = 0; i < N; i++) {
final NotificationChannel nc = r.channels.valueAt(i);
if (groupId.equals(nc.getGroup())) {
+ groupBypassedDnd |= nc.canBypassDnd();
deleteNotificationChannelLocked(nc, pkg, uid);
deletedChannels.add(nc);
}
}
}
+ if (groupBypassedDnd) {
+ updateChannelsBypassingDnd();
+ }
return deletedChannels;
}
@@ -1495,8 +1518,8 @@
public @NonNull List<String> deleteConversations(String pkg, int uid,
Set<String> conversationIds) {
+ List<String> deletedChannelIds = new ArrayList<>();
synchronized (mPackagePreferences) {
- List<String> deletedChannelIds = new ArrayList<>();
PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
if (r == null) {
return deletedChannelIds;
@@ -1517,11 +1540,11 @@
deletedChannelIds.add(nc.getId());
}
}
- if (!deletedChannelIds.isEmpty() && mAreChannelsBypassingDnd) {
- updateChannelsBypassingDnd();
- }
- return deletedChannelIds;
}
+ if (!deletedChannelIds.isEmpty() && mAreChannelsBypassingDnd) {
+ updateChannelsBypassingDnd();
+ }
+ return deletedChannelIds;
}
@Override
@@ -1554,8 +1577,7 @@
synchronized (mPackagePreferences) {
final PackagePreferences r = mPackagePreferences.get(
packagePreferencesKey(pkg, userId));
- // notifications from this package aren't blocked
- if (r != null && r.importance != IMPORTANCE_NONE) {
+ if (r != null) {
for (NotificationChannel channel : r.channels.values()) {
if (channelIsLiveLocked(r, channel) && channel.canBypassDnd()) {
channels.add(channel);
@@ -1622,74 +1644,62 @@
}
/**
- * Returns the number of apps that have at least one notification channel that can bypass DND
- * for given particular user
- */
- public int getAppsBypassingDndCount(int userId) {
- int count = 0;
- synchronized (mPackagePreferences) {
- final int numPackagePreferences = mPackagePreferences.size();
- for (int i = 0; i < numPackagePreferences; i++) {
- final PackagePreferences r = mPackagePreferences.valueAt(i);
- // Package isn't associated with this userId or notifications from this package are
- // blocked
- if (userId != UserHandle.getUserId(r.uid) || r.importance == IMPORTANCE_NONE) {
- continue;
- }
-
- for (NotificationChannel channel : r.channels.values()) {
- if (channelIsLiveLocked(r, channel) && channel.canBypassDnd()) {
- count++;
- break;
- }
- }
- }
- }
- return count;
- }
-
- /**
* Syncs {@link #mAreChannelsBypassingDnd} with the current user's notification policy before
* updating
*/
private void syncChannelsBypassingDnd() {
mAreChannelsBypassingDnd = (mZenModeHelper.getNotificationPolicy().state
& NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND) == 1;
+
updateChannelsBypassingDnd();
}
/**
* Updates the user's NotificationPolicy based on whether the current userId
* has channels bypassing DND
- * @param userId
*/
private void updateChannelsBypassingDnd() {
+ ArraySet<Pair<String, Integer>> candidatePkgs = new ArraySet<>();
+
synchronized (mPackagePreferences) {
final int numPackagePreferences = mPackagePreferences.size();
for (int i = 0; i < numPackagePreferences; i++) {
final PackagePreferences r = mPackagePreferences.valueAt(i);
- // Package isn't associated with the current userId or notifications from this
- // package are blocked
- if (mCurrentUserId != UserHandle.getUserId(r.uid)
- || r.importance == IMPORTANCE_NONE) {
+ // Package isn't associated with the current userId
+ if (mCurrentUserId != UserHandle.getUserId(r.uid)) {
continue;
}
for (NotificationChannel channel : r.channels.values()) {
if (channelIsLiveLocked(r, channel) && channel.canBypassDnd()) {
- if (!mAreChannelsBypassingDnd) {
- mAreChannelsBypassingDnd = true;
- updateZenPolicy(true);
- }
- return;
+ candidatePkgs.add(new Pair(r.pkg, r.uid));
+ break;
}
}
}
}
- // If no channels bypass DND, update the zen policy once to disable DND bypass.
- if (mAreChannelsBypassingDnd) {
- mAreChannelsBypassingDnd = false;
- updateZenPolicy(false);
+ for (int i = candidatePkgs.size() - 1; i >= 0; i--) {
+ Pair<String, Integer> app = candidatePkgs.valueAt(i);
+ if (mPermissionHelper.isMigrationEnabled()) {
+ if (!mPermissionHelper.hasPermission(app.second)) {
+ candidatePkgs.removeAt(i);
+ }
+ } else {
+ synchronized (mPackagePreferences) {
+ PackagePreferences r = getPackagePreferencesLocked(app.first, app.second);
+ if (r == null) {
+ continue;
+ }
+ if (r.importance == IMPORTANCE_NONE) {
+ candidatePkgs.removeAt(i);
+ }
+ }
+ }
+ }
+ boolean haveBypassingApps = candidatePkgs.size() > 0;
+ if (mAreChannelsBypassingDnd != haveBypassingApps) {
+ mAreChannelsBypassingDnd = haveBypassingApps;
+ updateZenPolicy(mAreChannelsBypassingDnd);
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 2894708..87ce1ce 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -44,6 +44,8 @@
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.media.PlaybackParams;
+import android.media.tv.BroadcastInfoRequest;
+import android.media.tv.BroadcastInfoResponse;
import android.media.tv.DvbDeviceInfo;
import android.media.tv.ITvInputClient;
import android.media.tv.ITvInputHardware;
@@ -2327,6 +2329,29 @@
}
@Override
+ public void requestBroadcastInfo(IBinder sessionToken, BroadcastInfoRequest request,
+ int userId) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
+ final int resolvedUserId = resolveCallingUserId(callingPid, callingUid,
+ userId, "requestBroadcastInfo");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ try {
+ SessionState sessionState = getSessionStateLocked(sessionToken, callingUid,
+ resolvedUserId);
+ getSessionLocked(sessionState).requestBroadcastInfo(request);
+ } catch (RemoteException | SessionNotFoundException e) {
+ Slog.e(TAG, "error in requestBroadcastInfo", e);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ };
+ }
+
+ @Override
public int getClientPid(String sessionId) {
ensureTunerResourceAccessPermission();
final long identity = Binder.clearCallingIdentity();
@@ -3342,6 +3367,23 @@
}
}
}
+
+ @Override
+ public void onBroadcastInfoResponse (BroadcastInfoResponse response) {
+ synchronized (mLock) {
+ if (DEBUG) {
+ Slog.d(TAG, "onBroadcastInfoResponse()");
+ }
+ if (mSessionState.session == null || mSessionState.client == null) {
+ return;
+ }
+ try {
+ mSessionState.client.onBroadcastInfoResponse(response, mSessionState.seq);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "error in onBroadcastInfoResponse", e);
+ }
+ }
+ }
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b407886..ab61a4b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -154,6 +154,7 @@
import static com.android.server.wm.ActivityRecordProto.IS_WAITING_FOR_TRANSITION_START;
import static com.android.server.wm.ActivityRecordProto.LAST_ALL_DRAWN;
import static com.android.server.wm.ActivityRecordProto.LAST_SURFACE_SHOWING;
+import static com.android.server.wm.ActivityRecordProto.MIN_ASPECT_RATIO;
import static com.android.server.wm.ActivityRecordProto.NAME;
import static com.android.server.wm.ActivityRecordProto.NUM_DRAWN_WINDOWS;
import static com.android.server.wm.ActivityRecordProto.NUM_INTERESTING_WINDOWS;
@@ -8925,6 +8926,7 @@
}
proto.write(PIP_AUTO_ENTER_ENABLED, pictureInPictureArgs.isAutoEnterEnabled());
proto.write(IN_SIZE_COMPAT_MODE, inSizeCompatMode());
+ proto.write(MIN_ASPECT_RATIO, info.getMinAspectRatio());
}
@Override
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index e505d85..64950c7 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -664,13 +664,23 @@
* This setting is persisted and will overlay on top of the system locales for
* the said application.
* @return the current {@link PackageConfigurationUpdater} updated with the provided locale.
+ *
+ * <p>NOTE: This method should not be called by clients directly to set app locales,
+ * instead use the {@link LocaleManagerService#setApplicationLocales}
*/
PackageConfigurationUpdater setLocales(LocaleList locales);
/**
* Commit changes.
+ * @return true if the configuration changes were persisted,
+ * false if there were no changes, or if erroneous inputs were provided, such as:
+ * <ui>
+ * <li>Invalid packageName</li>
+ * <li>Invalid userId</li>
+ * <li>no WindowProcessController found for the package</li>
+ * </ui>
*/
- void commit();
+ boolean commit();
}
/**
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index 38e1c99..fa43b39 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -31,7 +31,7 @@
import android.view.InputApplicationHandle;
import com.android.server.am.ActivityManagerService;
-import com.android.server.am.CriticalEventLog;
+import com.android.server.criticalevents.CriticalEventLog;
import java.io.File;
import java.util.ArrayList;
diff --git a/services/core/java/com/android/server/wm/PackageConfigPersister.java b/services/core/java/com/android/server/wm/PackageConfigPersister.java
index 081a53e..6de8ef7 100644
--- a/services/core/java/com/android/server/wm/PackageConfigPersister.java
+++ b/services/core/java/com/android/server/wm/PackageConfigPersister.java
@@ -172,7 +172,7 @@
}
@GuardedBy("mLock")
- void updateFromImpl(String packageName, int userId,
+ boolean updateFromImpl(String packageName, int userId,
PackageConfigurationUpdaterImpl impl) {
synchronized (mLock) {
PackageConfigRecord record = findRecordOrCreate(mModified, packageName, userId);
@@ -198,7 +198,7 @@
}
if (!updateNightMode(record, writeRecord) && !updateLocales(record, writeRecord)) {
- return;
+ return false;
}
if (DEBUG) {
@@ -206,6 +206,7 @@
}
mPersisterQueue.addItem(new WriteProcessItem(writeRecord), false /* flush */);
}
+ return true;
}
}
diff --git a/services/core/java/com/android/server/wm/PackageConfigurationUpdaterImpl.java b/services/core/java/com/android/server/wm/PackageConfigurationUpdaterImpl.java
index 8bbcf1f..0cd3680 100644
--- a/services/core/java/com/android/server/wm/PackageConfigurationUpdaterImpl.java
+++ b/services/core/java/com/android/server/wm/PackageConfigurationUpdaterImpl.java
@@ -68,7 +68,7 @@
}
@Override
- public void commit() {
+ public boolean commit() {
synchronized (this) {
synchronized (mAtm.mGlobalLock) {
final long ident = Binder.clearCallingIdentity();
@@ -79,7 +79,7 @@
if (wpc == null) {
Slog.w(TAG, "commit: Override application configuration failed: "
+ "cannot find pid " + mPid);
- return;
+ return false;
}
uid = wpc.mUid;
mUserId = wpc.mUserId;
@@ -90,11 +90,12 @@
if (uid < 0) {
Slog.w(TAG, "commit: update of application configuration failed: "
+ "userId or packageName not valid " + mUserId);
- return;
+ return false;
}
}
updateConfig(uid, mPackageName);
- mAtm.mPackageConfigPersister.updateFromImpl(mPackageName, mUserId, this);
+ return mAtm.mPackageConfigPersister
+ .updateFromImpl(mPackageName, mUserId, this);
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index af38641..81878e3 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -1559,7 +1559,9 @@
// activity as it could lead to incorrect display metrics. For ex, IME services
// expect their config to match the config of the display with the IME window
// showing.
+ // If the configuration has been overridden by previous activity, empty it.
mIsActivityConfigOverrideAllowed = false;
+ unregisterActivityConfigurationListener();
break;
default:
break;
diff --git a/services/tests/servicestests/src/com/android/server/OWNERS b/services/tests/servicestests/src/com/android/server/OWNERS
index f1402ea..6a7d298 100644
--- a/services/tests/servicestests/src/com/android/server/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/OWNERS
@@ -3,4 +3,5 @@
per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS
per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS
per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
+per-file BatteryServiceTest.java = file:platform/hardware/interfaces:/health/aidl/OWNERS
per-file GestureLauncherServiceTest.java = file:platform/packages/apps/EmergencyInfo:/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/am/CriticalEventLogTest.java b/services/tests/servicestests/src/com/android/server/criticalevents/CriticalEventLogTest.java
similarity index 96%
rename from services/tests/servicestests/src/com/android/server/am/CriticalEventLogTest.java
rename to services/tests/servicestests/src/com/android/server/criticalevents/CriticalEventLogTest.java
index 903d7f2..dca666c 100644
--- a/services/tests/servicestests/src/com/android/server/am/CriticalEventLogTest.java
+++ b/services/tests/servicestests/src/com/android/server/criticalevents/CriticalEventLogTest.java
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-package com.android.server.am;
+package com.android.server.criticalevents;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import com.android.framework.protobuf.nano.MessageNano;
-import com.android.server.am.CriticalEventLog.ILogLoader;
-import com.android.server.am.CriticalEventLog.LogLoader;
-import com.android.server.am.nano.CriticalEventLogProto;
-import com.android.server.am.nano.CriticalEventLogStorageProto;
-import com.android.server.am.nano.CriticalEventProto;
-import com.android.server.am.nano.CriticalEventProto.HalfWatchdog;
-import com.android.server.am.nano.CriticalEventProto.Watchdog;
+import com.android.server.criticalevents.CriticalEventLog.ILogLoader;
+import com.android.server.criticalevents.CriticalEventLog.LogLoader;
+import com.android.server.criticalevents.nano.CriticalEventLogProto;
+import com.android.server.criticalevents.nano.CriticalEventLogStorageProto;
+import com.android.server.criticalevents.nano.CriticalEventProto;
+import com.android.server.criticalevents.nano.CriticalEventProto.HalfWatchdog;
+import com.android.server.criticalevents.nano.CriticalEventProto.Watchdog;
import org.junit.Before;
import org.junit.Rule;
diff --git a/services/tests/servicestests/src/com/android/server/locales/FakePackageConfigurationUpdater.java b/services/tests/servicestests/src/com/android/server/locales/FakePackageConfigurationUpdater.java
index 1613b11..6cdae53 100644
--- a/services/tests/servicestests/src/com/android/server/locales/FakePackageConfigurationUpdater.java
+++ b/services/tests/servicestests/src/com/android/server/locales/FakePackageConfigurationUpdater.java
@@ -43,7 +43,9 @@
}
@Override
- public void commit() {}
+ public boolean commit() {
+ return mLocales != null;
+ }
/**
* Returns the locales that were stored during the test run. Returns {@code null} if no locales
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 16ee1e8..f61d300 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -132,6 +132,7 @@
import android.content.pm.IPackageManager;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
@@ -181,7 +182,6 @@
import android.util.Xml;
import android.widget.RemoteViews;
-import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
import com.android.internal.app.IAppOpsService;
@@ -248,6 +248,8 @@
@Mock
private PackageManager mPackageManagerClient;
@Mock
+ private PackageManagerInternal mPackageManagerInternal;
+ @Mock
private WindowManagerInternal mWindowManagerInternal;
@Mock
private PermissionHelper mPermissionHelper;
@@ -375,6 +377,8 @@
LocalServices.addService(DeviceIdleInternal.class, deviceIdleInternal);
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
LocalServices.addService(ActivityManagerInternal.class, mAmi);
+ LocalServices.removeServiceForTest(PackageManagerInternal.class);
+ LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager);
doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
@@ -1035,7 +1039,7 @@
NotificationRecord r = generateNotificationRecord(channel);
// isBlocked is only used for user blocking, not app suspension
- assertFalse(mService.isBlocked(r, mUsageStats));
+ assertFalse(mService.isRecordBlockedLocked(r));
}
@Test
@@ -1045,8 +1049,7 @@
NotificationChannel channel = new NotificationChannel("id", "name",
NotificationManager.IMPORTANCE_NONE);
NotificationRecord r = generateNotificationRecord(channel);
- assertTrue(mService.isBlocked(r, mUsageStats));
- verify(mUsageStats, times(1)).registerBlocked(eq(r));
+ assertTrue(mService.isRecordBlockedLocked(r));
mBinderService.createNotificationChannels(
PKG, new ParceledListSlice(Arrays.asList(channel)));
@@ -1143,8 +1146,7 @@
NotificationManager.IMPORTANCE_HIGH);
channel.setGroup("something");
NotificationRecord r = generateNotificationRecord(channel);
- assertTrue(mService.isBlocked(r, mUsageStats));
- verify(mUsageStats, times(1)).registerBlocked(eq(r));
+ assertTrue(mService.isRecordBlockedLocked(r));
}
@Test
@@ -1282,6 +1284,40 @@
}
@Test
+ public void testBlockedNotifications_blockedByUser() throws Exception {
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
+ when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
+
+ NotificationChannel channel = new NotificationChannel("id", "name",
+ NotificationManager.IMPORTANCE_HIGH);
+ NotificationRecord r = generateNotificationRecord(channel);
+ mService.addEnqueuedNotification(r);
+
+ when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(IMPORTANCE_NONE);
+
+ NotificationManagerService.PostNotificationRunnable runnable =
+ mService.new PostNotificationRunnable(r.getKey());
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+ }
+
+ @Test
+ public void testEnqueueNotification_appBlocked() throws Exception {
+ mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueueNotification_appBlocked", 0,
+ generateNotificationRecord(null).getNotification(), 0);
+ waitForIdle();
+ verify(mWorkerHandler, never()).post(
+ any(NotificationManagerService.EnqueueNotificationRunnable.class));
+ }
+
+ @Test
public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
mBinderService.enqueueNotificationWithTag(PKG, PKG,
"testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
@@ -8307,4 +8343,15 @@
public void testMigrationDisabledByDefault() {
assertThat(mService.mEnableAppSettingMigration).isFalse();
}
+
+ @Test
+ public void testGetNotificationChannelsBypassingDnd_blocked() throws RemoteException {
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mPreferencesHelper.getImportance(PKG, mUid)).thenReturn(IMPORTANCE_NONE);
+
+ assertThat(mBinderService.getNotificationChannelsBypassingDnd(PKG, mUid).getList())
+ .isEmpty();
+ verify(mPermissionHelper, never()).hasPermission(anyInt());
+ verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(PKG, mUid);
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
index 36d6945..3ec8729 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
@@ -76,6 +76,7 @@
import android.content.pm.IPackageManager;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
@@ -86,6 +87,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -159,6 +161,8 @@
@Mock
private PackageManager mPackageManagerClient;
@Mock
+ private PackageManagerInternal mPackageManagerInternal;
+ @Mock
private WindowManagerInternal mWindowManagerInternal;
@Mock
private PermissionHelper mPermissionHelper;
@@ -279,6 +283,8 @@
LocalServices.addService(DeviceIdleInternal.class, deviceIdleInternal);
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
LocalServices.addService(ActivityManagerInternal.class, mAmi);
+ LocalServices.removeServiceForTest(PackageManagerInternal.class);
+ LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager);
doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
@@ -612,4 +618,49 @@
assertEquals(PKG, captor.getValue().getPackage());
assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
}
+
+ @Test
+ public void testGetNotificationChannelsBypassingDnd_blocked() throws RemoteException {
+ mService.setPreferencesHelper(mPreferencesHelper);
+
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
+
+ assertThat(mBinderService.getNotificationChannelsBypassingDnd(PKG, mUid).getList())
+ .isEmpty();
+ verify(mPreferencesHelper, never()).getImportance(anyString(), anyInt());
+ verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(PKG, mUid);
+ }
+
+ @Test
+ public void testBlockedNotifications_blockedByUser() throws Exception {
+ when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
+ when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
+
+ NotificationChannel channel = new NotificationChannel("id", "name",
+ NotificationManager.IMPORTANCE_HIGH);
+ NotificationRecord r = generateNotificationRecord(channel);
+ mService.addEnqueuedNotification(r);
+
+ when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);
+
+ NotificationManagerService.PostNotificationRunnable runnable =
+ mService.new PostNotificationRunnable(r.getKey());
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+ }
+
+ @Test
+ public void testEnqueueNotification_appBlocked() throws Exception {
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueueNotification_appBlocked", 0,
+ generateNotificationRecord(null).getNotification(), 0);
+ waitForIdle();
+ verify(mWorkerHandler, never()).post(
+ any(NotificationManagerService.EnqueueNotificationRunnable.class));
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index f72d39a..55b12dd 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -62,6 +62,7 @@
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -91,7 +92,8 @@
Method[] allMethods = PermissionHelper.class.getDeclaredMethods();
for (Method method : allMethods) {
- if (Modifier.isPublic(method.getModifiers())) {
+ if (Modifier.isPublic(method.getModifiers()) &&
+ !Objects.equals("isMigrationEnabled", method.getName())) {
Parameter[] params = method.getParameters();
List<Object> args = Lists.newArrayListWithCapacity(params.length);
for (int i = 0; i < params.length; i++) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index ea5de0c..5324ec5f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -153,7 +153,7 @@
Uri.parse("content://" + TEST_AUTHORITY
+ "/internal/audio/media/10?title=Test&canonical=1");
- @Mock NotificationUsageStats mUsageStats;
+ @Mock PermissionHelper mPermissionHelper;
@Mock RankingHandler mHandler;
@Mock PackageManager mPm;
IContentProvider mTestIContentProvider;
@@ -269,8 +269,8 @@
mStatsEventBuilderFactory = new WrappedSysUiStatsEvent.WrappedBuilderFactory();
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
- mAppOpsManager, mStatsEventBuilderFactory);
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
resetZenModeHelper();
mAudioAttributes = new AudioAttributes.Builder()
@@ -1393,16 +1393,6 @@
assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
user).getList().size());
- // block notifications from this app
- mHelper.setEnabled(PKG_N_MR1, user, false);
- assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
- user).getList().size());
-
- // re-enable notifications from this app
- mHelper.setEnabled(PKG_N_MR1, user, true);
- assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
- user).getList().size());
-
// setBypassDnd false for some channels
channel1.setBypassDnd(false);
channel2.setBypassDnd(false);
@@ -1416,78 +1406,7 @@
}
@Test
- public void testGetAppsBypassingDndCount_noAppsBypassing() throws Exception {
- assertEquals(0, mHelper.getAppsBypassingDndCount(USER.getIdentifier()));
- }
-
- @Test
- public void testGetAppsBypassingDndCount_noAppsForUserIdBypassing() throws Exception {
- int user = 9;
- NotificationChannel channel = new NotificationChannel("id", "name",
- NotificationManager.IMPORTANCE_MAX);
- channel.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
-
- assertEquals(0, mHelper.getAppsBypassingDndCount(user));
- }
-
- @Test
- public void testGetAppsBypassingDndCount_oneChannelBypassing_groupBlocked() {
- int user = USER.getIdentifier();
- NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
- NotificationChannel channel1 = new NotificationChannel("id1", "name1",
- NotificationManager.IMPORTANCE_MAX);
- channel1.setBypassDnd(true);
- channel1.setGroup(ncg.getId());
- mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ true);
- mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
-
- assertEquals(1, mHelper.getAppsBypassingDndCount(user));
-
- // disable group
- ncg.setBlocked(true);
- mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg, /* fromTargetApp */ false);
- assertEquals(0, mHelper.getAppsBypassingDndCount(user));
- }
-
- @Test
- public void testGetAppsBypassingDndCount_oneAppBypassing() {
- int user = USER.getIdentifier();
- NotificationChannel channel1 = new NotificationChannel("id1", "name1",
- NotificationManager.IMPORTANCE_MAX);
- NotificationChannel channel2 = new NotificationChannel("id2", "name2",
- NotificationManager.IMPORTANCE_MAX);
- NotificationChannel channel3 = new NotificationChannel("id3", "name3",
- NotificationManager.IMPORTANCE_MAX);
- channel1.setBypassDnd(true);
- channel2.setBypassDnd(true);
- channel3.setBypassDnd(true);
- // has DND access, so can set bypassDnd attribute
- mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
- mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
- mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
- assertEquals(1, mHelper.getAppsBypassingDndCount(user));
-
- // block notifications from this app
- mHelper.setEnabled(PKG_N_MR1, user, false);
- assertEquals(0, mHelper.getAppsBypassingDndCount(user)); // no apps can bypass dnd
-
- // re-enable notifications from this app
- mHelper.setEnabled(PKG_N_MR1, user, true);
- assertEquals(1, mHelper.getAppsBypassingDndCount(user));
-
- // setBypassDnd false for some channels
- channel1.setBypassDnd(false);
- channel2.setBypassDnd(false);
- assertEquals(1, mHelper.getAppsBypassingDndCount(user));
-
- // setBypassDnd false for rest of the channels
- channel3.setBypassDnd(false);
- assertEquals(0, mHelper.getAppsBypassingDndCount(user));
- }
-
- @Test
- public void testCreateAndDeleteCanChannelsBypassDnd() throws Exception {
+ public void testCreateAndDeleteCanChannelsBypassDnd_localSettings() throws Exception {
int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
// create notification channel that can't bypass dnd
@@ -1501,6 +1420,70 @@
// create notification channel that can bypass dnd
// expected result: areChannelsBypassingDnd = true
+ assertTrue(mHelper.getImportance(PKG_N_MR1, uid) != IMPORTANCE_NONE);
+ NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
+ channel2.setBypassDnd(true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ assertTrue(mHelper.areChannelsBypassingDnd());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ resetZenModeHelper();
+
+ // delete channels
+ mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId());
+ assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ resetZenModeHelper();
+
+ mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId());
+ assertFalse(mHelper.areChannelsBypassingDnd());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ resetZenModeHelper();
+ }
+
+ @Test
+ public void testCreateAndUpdateChannelsBypassingDnd_permissionHelper() {
+ int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
+
+ when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
+ when(mPermissionHelper.hasPermission(uid)).thenReturn(true);
+
+ // create notification channel that can't bypass dnd
+ // expected result: areChannelsBypassingDnd = false
+ // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
+ NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+ assertFalse(mHelper.areChannelsBypassingDnd());
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ resetZenModeHelper();
+
+ // Recreate a channel & now the app has dnd access granted and can set the bypass dnd field
+ NotificationChannel update = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
+ update.setBypassDnd(true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, update, true, true);
+
+ assertTrue(mHelper.areChannelsBypassingDnd());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ resetZenModeHelper();
+ }
+
+ @Test
+ public void testCreateAndDeleteCanChannelsBypassDnd_permissionHelper() throws Exception {
+ int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
+
+ when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
+ when(mPermissionHelper.hasPermission(uid)).thenReturn(true);
+
+ // create notification channel that can't bypass dnd
+ // expected result: areChannelsBypassingDnd = false
+ // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
+ NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+ assertFalse(mHelper.areChannelsBypassingDnd());
+ verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+ resetZenModeHelper();
+
+ // create notification channel that can bypass dnd, using local app level settings
+ // expected result: areChannelsBypassingDnd = true
NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel2.setBypassDnd(true);
mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
@@ -1521,6 +1504,79 @@
}
@Test
+ public void testBlockedGroupDoesNotBypassDnd() throws Exception {
+ int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
+
+ // start in a 'allowed to bypass dnd state'
+ mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
+ NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
+ when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
+ mAppOpsManager, mStatsEventBuilderFactory);
+
+
+ // create notification channel that can bypass dnd, but app is blocked
+ // expected result: areChannelsBypassingDnd = false
+ NotificationChannelGroup group = new NotificationChannelGroup("group", "group");
+ group.setBlocked(true);
+ mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, group, false);
+ NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
+ channel2.setGroup("group");
+ channel2.setBypassDnd(true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ assertFalse(mHelper.areChannelsBypassingDnd());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ resetZenModeHelper();
+ }
+
+ @Test
+ public void testBlockedAppsDoNotBypassDnd_localSettings() throws Exception {
+ int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
+
+ // start in a 'allowed to bypass dnd state'
+ mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
+ NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
+ when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
+ mAppOpsManager, mStatsEventBuilderFactory);
+
+ mHelper.setImportance(PKG_N_MR1, uid, IMPORTANCE_NONE);
+ // create notification channel that can bypass dnd, but app is blocked
+ // expected result: areChannelsBypassingDnd = false
+ NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
+ channel2.setBypassDnd(true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ assertFalse(mHelper.areChannelsBypassingDnd());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ resetZenModeHelper();
+ }
+
+ @Test
+ public void testBlockedAppsDoNotBypassDnd_permissionHelper() throws Exception {
+ int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
+ when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
+ when(mPermissionHelper.hasPermission(uid)).thenReturn(false);
+ // start in a 'allowed to bypass dnd state'
+ mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
+ NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
+ when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
+ mAppOpsManager, mStatsEventBuilderFactory);
+
+ // create notification channel that can bypass dnd, but app is blocked
+ // expected result: areChannelsBypassingDnd = false
+ NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
+ channel2.setBypassDnd(true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ assertFalse(mHelper.areChannelsBypassingDnd());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ resetZenModeHelper();
+ }
+
+ @Test
public void testUpdateCanChannelsBypassDnd() throws Exception {
int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
@@ -1557,7 +1613,8 @@
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
assertFalse(mHelper.areChannelsBypassingDnd());
verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
@@ -1569,7 +1626,8 @@
// start notification policy off with mAreChannelsBypassingDnd = false
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
assertFalse(mHelper.areChannelsBypassingDnd());
verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
@@ -2355,7 +2413,8 @@
+ "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+ "</package>\n"
+ "</ranking>\n";
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
@@ -2368,7 +2427,8 @@
mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -2465,7 +2525,8 @@
mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -2477,7 +2538,8 @@
mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -2490,7 +2552,8 @@
mHelper.revokeNotificationDelegate(PKG_O, UID_O);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -2503,7 +2566,8 @@
mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -2522,7 +2586,8 @@
mHelper.revokeNotificationDelegate(PKG_O, UID_O);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -2541,7 +2606,8 @@
assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -2596,7 +2662,8 @@
mHelper.getAppLockedFields(PKG_O, UID_O));
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -2633,7 +2700,8 @@
mHelper.getAppLockedFields(PKG_O, UID_O));
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
@@ -3235,7 +3303,8 @@
@Test
public void testPlaceholderConversationId_shortcutRequired() throws Exception {
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
final String xml = "<ranking version=\"1\">\n"
@@ -3254,7 +3323,8 @@
@Test
public void testNormalConversationId_shortcutRequired() throws Exception {
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
final String xml = "<ranking version=\"1\">\n"
@@ -3273,7 +3343,8 @@
@Test
public void testNoConversationId_shortcutRequired() throws Exception {
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
final String xml = "<ranking version=\"1\">\n"
@@ -3292,7 +3363,8 @@
@Test
public void testDeleted_noTime() throws Exception {
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
final String xml = "<ranking version=\"1\">\n"
@@ -3311,7 +3383,8 @@
@Test
public void testDeleted_twice() throws Exception {
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
mHelper.createNotificationChannel(
@@ -3322,7 +3395,8 @@
@Test
public void testDeleted_recentTime() throws Exception {
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
mHelper.createNotificationChannel(
@@ -3339,7 +3413,8 @@
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
null);
parser.nextTag();
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
@@ -3350,7 +3425,8 @@
@Test
public void testUnDelete_time() throws Exception {
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
mHelper.createNotificationChannel(
@@ -3369,7 +3445,8 @@
@Test
public void testDeleted_longTime() throws Exception {
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
mAppOpsManager, mStatsEventBuilderFactory);
long time = System.currentTimeMillis() - (DateUtils.DAY_IN_MILLIS * 30);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
index 8edd111..59d9a35 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -48,6 +48,7 @@
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 4c3c318..b0fb812 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -839,6 +839,30 @@
wpc.getConfiguration().getLocales());
}
+ @Test
+ public void testPackageConfigUpdate_commitConfig_configSuccessfullyApplied() {
+ Configuration config = mAtm.getGlobalConfiguration();
+ config.setLocales(LocaleList.forLanguageTags("en-XC"));
+ mAtm.updateGlobalConfigurationLocked(config, true, true,
+ DEFAULT_USER_ID);
+ WindowProcessController wpc = createWindowProcessController(
+ DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
+ mAtm.mProcessMap.put(Binder.getCallingPid(), wpc);
+ mAtm.mInternal.onProcessAdded(wpc);
+
+ ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
+ mAtm.mInternal.createPackageConfigurationUpdater(DEFAULT_PACKAGE_NAME,
+ DEFAULT_USER_ID);
+ // committing new configuration returns true;
+ assertTrue(packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB"))
+ .commit());
+ // applying the same configuration returns false.
+ assertFalse(packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB"))
+ .commit());
+ assertTrue(packageConfigUpdater.setLocales(LocaleList.getEmptyLocaleList())
+ .setNightMode(Configuration.UI_MODE_NIGHT_UNDEFINED).commit());
+ }
+
private WindowProcessController createWindowProcessController(String packageName,
int userId) {
WindowProcessListener mMockListener = Mockito.mock(WindowProcessListener.class);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 339249b..ad042dd 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -16,6 +16,7 @@
package com.android.server.usage;
+import android.annotation.Nullable;
import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
@@ -788,7 +789,7 @@
public interface StatCombiner<T> {
/**
- * Implementations should extract interesting from <code>stats</code> and add it
+ * Implementations should extract interesting information from <code>stats</code> and add it
* to the <code>accumulatedResult</code> list.
*
* If the <code>stats</code> object is mutable, <code>mutable</code> will be true,
@@ -805,29 +806,24 @@
/**
* Find all {@link IntervalStats} for the given range and interval type.
*/
+ @Nullable
public <T> List<T> queryUsageStats(int intervalType, long beginTime, long endTime,
StatCombiner<T> combiner) {
+ // mIntervalDirs is final. Accessing its size without holding the lock should be fine.
+ if (intervalType < 0 || intervalType >= mIntervalDirs.length) {
+ throw new IllegalArgumentException("Bad interval type " + intervalType);
+ }
+
+ if (endTime <= beginTime) {
+ if (DEBUG) {
+ Slog.d(TAG, "endTime(" + endTime + ") <= beginTime(" + beginTime + ")");
+ }
+ return null;
+ }
+
synchronized (mLock) {
- if (intervalType < 0 || intervalType >= mIntervalDirs.length) {
- throw new IllegalArgumentException("Bad interval type " + intervalType);
- }
-
final TimeSparseArray<AtomicFile> intervalStats = mSortedStatFiles[intervalType];
- if (endTime <= beginTime) {
- if (DEBUG) {
- Slog.d(TAG, "endTime(" + endTime + ") <= beginTime(" + beginTime + ")");
- }
- return null;
- }
-
- int startIndex = intervalStats.closestIndexOnOrBefore(beginTime);
- if (startIndex < 0) {
- // All the stats available have timestamps after beginTime, which means they all
- // match.
- startIndex = 0;
- }
-
int endIndex = intervalStats.closestIndexOnOrBefore(endTime);
if (endIndex < 0) {
// All the stats start after this range ends, so nothing matches.
@@ -849,6 +845,13 @@
}
}
+ int startIndex = intervalStats.closestIndexOnOrBefore(beginTime);
+ if (startIndex < 0) {
+ // All the stats available have timestamps after beginTime, which means they all
+ // match.
+ startIndex = 0;
+ }
+
final ArrayList<T> results = new ArrayList<>();
for (int i = startIndex; i <= endIndex; i++) {
final AtomicFile f = intervalStats.valueAt(i);
@@ -985,7 +988,6 @@
}
}
-
private static long parseBeginTime(AtomicFile file) throws IOException {
return parseBeginTime(file.getBaseFile());
}
@@ -1233,7 +1235,6 @@
}
}
-
/* Backup/Restore Code */
byte[] getBackupPayload(String key) {
return getBackupPayload(key, BACKUP_VERSION);
diff --git a/tests/HwAccelerationTest/Android.bp b/tests/HwAccelerationTest/Android.bp
index 7606322..e618ed1 100644
--- a/tests/HwAccelerationTest/Android.bp
+++ b/tests/HwAccelerationTest/Android.bp
@@ -25,7 +25,13 @@
android_test {
name: "HwAccelerationTest",
- srcs: ["**/*.java"],
+ jni_libs: [
+ "libhwaccelerationtest_jni",
+ ],
+ srcs: [
+ "**/*.java",
+ "**/*.kt",
+ ],
platform_apis: true,
certificate: "platform",
}
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 04a55d6..269c575 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -436,6 +436,15 @@
</intent-filter>
</activity>
+ <activity android:name=".PenStylusActivity"
+ android:label="Pen (BUGGED)/Draw"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="com.android.test.hwui.TEST"/>
+ </intent-filter>
+ </activity>
+
<activity android:name="GLTextureViewActivity"
android:label="TextureView/OpenGL"
android:exported="true">
diff --git a/tests/HwAccelerationTest/jni/Android.bp b/tests/HwAccelerationTest/jni/Android.bp
new file mode 100644
index 0000000..8edddab
--- /dev/null
+++ b/tests/HwAccelerationTest/jni/Android.bp
@@ -0,0 +1,44 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test_library {
+
+ name: "libhwaccelerationtest_jni",
+
+ cflags: [
+ "-Werror",
+ "-Wno-error=deprecated-declarations",
+ ],
+
+ gtest: false,
+
+ srcs: [
+ "native-lib.cpp",
+ ],
+
+ shared_libs: [
+ "libnativehelper",
+ "libandroid",
+ "liblog",
+ ],
+
+ stl: "c++_static",
+
+ sdk_version: "current",
+
+}
diff --git a/tests/HwAccelerationTest/jni/native-lib.cpp b/tests/HwAccelerationTest/jni/native-lib.cpp
new file mode 100644
index 0000000..d6b1c49
--- /dev/null
+++ b/tests/HwAccelerationTest/jni/native-lib.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#include <android/hardware_buffer.h>
+#include <android/hardware_buffer_jni.h>
+#include <android/native_window.h>
+#include <android/native_window_jni.h>
+#include <android/surface_control.h>
+#include <jni.h>
+
+struct MyWrapper {
+ MyWrapper(ANativeWindow* parent) {
+ surfaceControl = ASurfaceControl_createFromWindow(parent, "PenLayer");
+ }
+
+ ~MyWrapper() { ASurfaceControl_release(surfaceControl); }
+
+ void setBuffer(AHardwareBuffer* buffer) {
+ ASurfaceTransaction* transaction = ASurfaceTransaction_create();
+ ASurfaceTransaction_setBuffer(transaction, surfaceControl, buffer);
+ ASurfaceTransaction_setVisibility(transaction, surfaceControl,
+ ASURFACE_TRANSACTION_VISIBILITY_SHOW);
+ ASurfaceTransaction_apply(transaction);
+ ASurfaceTransaction_delete(transaction);
+ }
+
+ ASurfaceControl* surfaceControl = nullptr;
+};
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_com_android_test_hwui_FrontBufferedLayer_nCreate(JNIEnv* env, jobject jSurface) {
+ ANativeWindow* window = ANativeWindow_fromSurface(env, jSurface);
+ MyWrapper* wrapper = new MyWrapper(window);
+ ANativeWindow_release(window);
+ return reinterpret_cast<jlong>(wrapper);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_android_test_hwui_FrontBufferedLayer_nDestroy(jlong ptr) {
+ MyWrapper* wrapper = reinterpret_cast<MyWrapper*>(ptr);
+ delete wrapper;
+}
+
+extern "C" JNIEXPORT void JNICALL Java_com_android_test_hwui_FrontBufferedLayer_nUpdateBuffer(
+ JNIEnv* env, jlong ptr, jobject jbuffer) {
+ MyWrapper* wrapper = reinterpret_cast<MyWrapper*>(ptr);
+ AHardwareBuffer* buffer = AHardwareBuffer_fromHardwareBuffer(env, jbuffer);
+ wrapper->setBuffer(buffer);
+}
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/res/layout/pen_stylus.xml b/tests/HwAccelerationTest/res/layout/pen_stylus.xml
new file mode 100644
index 0000000..37aafed
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/pen_stylus.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<com.android.test.hwui.FrontBufferedLayer
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+/>
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/FrontBufferedLayer.kt b/tests/HwAccelerationTest/src/com/android/test/hwui/FrontBufferedLayer.kt
new file mode 100644
index 0000000..ebec22e
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/FrontBufferedLayer.kt
@@ -0,0 +1,132 @@
+/*
+ * 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.test.hwui
+
+import android.content.Context
+import android.graphics.BlendMode
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.Rect
+import android.hardware.HardwareBuffer
+import android.util.AttributeSet
+import android.view.InputDevice
+import android.view.MotionEvent
+import android.view.Surface
+import android.view.SurfaceHolder
+import android.view.SurfaceView
+import android.view.WindowInsets
+import android.view.WindowInsetsController
+
+class FrontBufferedLayer : SurfaceView, SurfaceHolder.Callback {
+ var mRenderer: PenStylusActivity.SingleBufferedCanvas? = null
+
+ constructor(context: Context) : super(context)
+ constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
+
+ init {
+ holder.addCallback(this)
+ setZOrderOnTop(true)
+ }
+
+ override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
+ nDestroy(mNativePtr)
+ mNativePtr = nCreate(holder.surface)
+ mRenderer = PenStylusActivity.SingleBufferedCanvas(width, height)
+ clearOverlay()
+
+ if ((false)) {
+ val canvas = holder.lockCanvas()
+ canvas.drawColor(Color.LTGRAY)
+ holder.unlockCanvasAndPost(canvas)
+ }
+ }
+
+ override fun surfaceDestroyed(holder: SurfaceHolder) {
+ mRenderer = null
+ nDestroy(mNativePtr)
+ mNativePtr = 0
+ }
+
+ override fun surfaceCreated(holder: SurfaceHolder) {
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ requestUnbufferedDispatch(InputDevice.SOURCE_CLASS_POINTER)
+ this.windowInsetsController?.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_DEFAULT)
+ this.windowInsetsController?.hide(WindowInsets.Type.navigationBars())
+ this.windowInsetsController?.hide(WindowInsets.Type.statusBars())
+ }
+
+ private fun clearOverlay() {
+ mRenderer?.let {
+ it.update(null) {
+ drawColor(Color.WHITE, BlendMode.SRC)
+ }
+ nUpdateBuffer(mNativePtr, it.mHardwareBuffer)
+ }
+ }
+
+ private var prevX: Float = 0f
+ private var prevY: Float = 0f
+ private val paint = Paint().also {
+ it.color = Color.BLACK
+ it.strokeWidth = 10f
+ it.isAntiAlias = true
+ }
+
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ if (!event.isFromSource(InputDevice.SOURCE_STYLUS)) {
+ if (event.action == MotionEvent.ACTION_DOWN) {
+ clearOverlay()
+ }
+ return true
+ }
+ val action = event.actionMasked
+ if (action == MotionEvent.ACTION_DOWN ||
+ action == MotionEvent.ACTION_MOVE) {
+ mRenderer?.let {
+ val left = minOf(prevX, event.x).toInt() - 10
+ val top = minOf(prevY, event.y).toInt() - 10
+ val right = maxOf(prevX, event.x).toInt() + 10
+ val bottom = maxOf(prevY, event.y).toInt() + 10
+ it.update(Rect(left, top, right, bottom)) {
+ if (action == MotionEvent.ACTION_MOVE) {
+ drawLine(prevX, prevY, event.x, event.y, paint)
+ }
+ drawCircle(event.x, event.y, 5f, paint)
+ }
+ nUpdateBuffer(mNativePtr, it.mHardwareBuffer)
+ }
+ prevX = event.x
+ prevY = event.y
+ }
+ return true
+ }
+
+ private var mNativePtr: Long = 0
+
+ private external fun nCreate(surface: Surface): Long
+ private external fun nDestroy(ptr: Long)
+ private external fun nUpdateBuffer(ptr: Long, buffer: HardwareBuffer)
+
+ companion object {
+ init {
+ System.loadLibrary("hwaccelerationtest_jni")
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PenStylusActivity.kt b/tests/HwAccelerationTest/src/com/android/test/hwui/PenStylusActivity.kt
new file mode 100644
index 0000000..1445b1d
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PenStylusActivity.kt
@@ -0,0 +1,85 @@
+/*
+ * 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.test.hwui
+
+import android.app.Activity
+import android.os.Bundle
+import android.hardware.HardwareBuffer
+import android.graphics.Canvas
+import android.graphics.PixelFormat
+import android.graphics.Rect
+import android.media.ImageReader
+import android.view.Surface
+import java.lang.IllegalArgumentException
+
+const val USAGE_HWC = 0x800L
+
+class PenStylusActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContentView(FrontBufferedLayer(this))
+ }
+
+ class SingleBufferedCanvas : AutoCloseable {
+ val mHardwareBuffer: HardwareBuffer
+ private var mCanvas: Canvas?
+ private val mImageReader: ImageReader
+ private val mSurface: Surface
+
+ constructor(width: Int, height: Int) {
+ mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1,
+ HardwareBuffer.USAGE_CPU_READ_RARELY or HardwareBuffer.USAGE_CPU_WRITE_RARELY or
+ HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or USAGE_HWC)
+
+ mSurface = mImageReader.surface
+ mSurface.unlockCanvasAndPost(mSurface.lockCanvas(null))
+ val image = mImageReader.acquireNextImage()
+ mHardwareBuffer = image.hardwareBuffer!!
+ image.close()
+ mCanvas = mSurface.lockCanvas(null)
+ }
+
+ fun lockCanvas(rect: Rect?): Canvas {
+ if (mCanvas != null) {
+ unlockCanvas(mCanvas!!)
+ }
+ mCanvas = mSurface.lockCanvas(rect)
+ return mCanvas!!
+ }
+
+ fun unlockCanvas(canvas: Canvas) {
+ if (this.mCanvas !== canvas) throw IllegalArgumentException()
+ mSurface.unlockCanvasAndPost(canvas)
+ this.mCanvas = null
+ mImageReader.acquireNextImage().close()
+ }
+
+ inline fun update(area: Rect?, func: Canvas.() -> Unit) {
+ val canvas = lockCanvas(area)
+ func(canvas)
+ unlockCanvas(canvas)
+ }
+
+ override fun close() {
+ mHardwareBuffer.close()
+ mSurface.unlockCanvasAndPost(mCanvas)
+ mImageReader.close()
+ }
+ }
+}
\ No newline at end of file